鱼C论坛

 找回密码
 立即注册
查看: 1751|回复: 8

[已解决]如何处理2048游戏中方块间的碰撞事件?

[复制链接]
发表于 2017-7-13 22:41:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我想用pygame做一个2048的小游戏,但是却卡在了方块之间的碰撞的事件处理上,碰撞后还要产生新的方块,这就有点迷惑了,请问有谁能提供一下解决思路吗,我小白一个
最佳答案
2017-7-13 23:05:56
仅供参考:

搜狗截图20170713230459.png

  1. import pygame, sys
  2. from pygame.locals import *
  3. import pygame.locals
  4. from pygame import key,event

  5. pygame.init()
  6. fpsClock = pygame.time.Clock()
  7. SIZE = 4
  8. BLOCKSIZE=100
  9. MAX=SIZE*BLOCKSIZE
  10. _GameEnd=None
  11. _GameOver=None
  12. windowSurfaceObj = pygame.display.set_mode((MAX,MAX))
  13. pygame.display.set_caption('2048')

  14. redColor = pygame.Color(255,0,0)
  15. greenColor = pygame.Color(0,255,0)
  16. blueColor = pygame.Color(0,0,255)
  17. whiteColor = pygame.Color (255,255,255)
  18. lightblue = pygame.Color(173, 216, 230)
  19. lighterblue = pygame.Color(235,255,255)
  20. grey =  pygame.Color(145,141,142)
  21. gold =  pygame.Color(255,215,0)
  22. black=  pygame.Color(0,0,0)
  23. granite = pygame.Color(131,126,124)
  24. box1 =  pygame.Color(201,196,194)
  25. color2 =(229,228,227)
  26. color4 = pygame.Color(229,182,147)

  27. colors = {2:(229,228,227),4:(229,228-20,227-40),8:(229,228-30,227-60),16:(229,150,100),
  28.           32:(200,100,50),64:(150,60,30),128:(255,219,90),
  29.           256:(229,200,70),512:(229,180,50),1024:(229,170,40),2048:(229,160,20),
  30.           4096:(0,0,0),8192:(0,0,100),16384:(30,0,0),32768:(60,0,0)}
  31. mousex,mousey = 0,0

  32. fontObj  = pygame.font.SysFont('verdana',32)
  33. fontObj2  = pygame.font.SysFont('verdana',32)
  34. fontObj16  = pygame.font.SysFont('verdana',28)
  35. fontObj128  = pygame.font.SysFont('verdana',26,bold=True)
  36. fontObj1024  = pygame.font.SysFont('verdana',24,bold=True)
  37. fontObj16384  = pygame.font.SysFont('verdana',23,bold=True)
  38. fontObjSmall  = pygame.font.SysFont('verdana',22,bold=True)
  39. fonts =[fontObj2,fontObj16,fontObj128,fontObj1024,fontObj16384,fontObjSmall]

  40. # soundObj = pygame.mixer.Sound('bounce.wav')
  41. lineArray = []
  42. for a in range(BLOCKSIZE,MAX,BLOCKSIZE) :
  43.     lineArray.append( (0,a))
  44.     lineArray.append((MAX,a))
  45.     lineArray.append((MAX,a+BLOCKSIZE))
  46. lineArray.append((MAX,0))
  47. lineArray.append((0,0))
  48. for a in range(BLOCKSIZE,MAX,BLOCKSIZE) :
  49.     lineArray.append( (a,0))
  50.     lineArray.append((a,MAX))
  51.     lineArray.append((a+BLOCKSIZE,400))
  52. print(lineArray)

  53. def processMovement(myList:list,directive:int):

  54.     print(myList)
  55.     newList=[]
  56.     Matrix = [[0 for x in range(SIZE)] for x in range(SIZE)]
  57.     for (x,y,z) in myList:
  58.         Matrix[y//BLOCKSIZE][x//BLOCKSIZE]=z

  59.     if directive == pygame.K_DOWN:  # 90 rotation
  60.         Matrix=[list(elem) for elem in zip(*Matrix[::-1])]
  61.         Matrix,score=addMatrix(Matrix)
  62.         Matrix=[list(elem[::-1]) for elem in zip(*Matrix[::-1])][::-1]
  63.     if directive == pygame.K_UP:
  64.         Matrix=[list(elem) for elem in zip(*Matrix)]
  65.         Matrix,score=addMatrix(Matrix)
  66.         Matrix=[list(elem) for elem in zip(*Matrix)]

  67.     elif directive == pygame.K_LEFT:  # no rotation
  68.         print('move left, no rotation\n')
  69.         Matrix,score=addMatrix(Matrix)
  70.     elif directive == pygame.K_RIGHT:  # 180 rotation
  71.         print('move right, rotate 180\n')
  72.         Matrix=[each [::-1] for each in Matrix[::-1]]
  73.         Matrix,score=addMatrix(Matrix)
  74.         Matrix=[each [::-1] for each in Matrix[::-1]]

  75.     for j,line in enumerate(Matrix):
  76.         for i,each in enumerate(line):
  77.             if each!=0:
  78.                 newList.append([i*BLOCKSIZE,j*BLOCKSIZE,each])

  79.     standStill = True if sorted(myList)==sorted(newList) else False
  80.     return newList,standStill,score

  81. def addMatrix(myList:list):

  82.     newList=[]
  83.     newLine=[]
  84.     score=0
  85.     lastPaired=False
  86.     print("before add ",myList)
  87.     for i,line in enumerate(myList):
  88.         for i,each in enumerate(line):
  89.             print("loop:",i,each)
  90.             if each ==0:
  91.                 pass
  92.             elif len(newLine)>0 and newLine[-1]==each and not lastPaired:
  93.                 print("what is this:",each)
  94.                 newLine[-1]= 2*int(each)
  95.                 score=score+2*int(each)
  96.                 lastPaired=True
  97.                 if  each==1048 and _GameEnd==None : _GameEnd=True
  98.             else:
  99.                 lastPaired=False
  100.                 newLine.append(int(each))
  101.                 print("appending",i)
  102.         lastPaired=False

  103.         newLine.extend( [0] *(SIZE-len(newLine)))
  104.         print("add test:",len(newLine))
  105.         newList.append(newLine)
  106.         newLine=[]

  107.     return newList,score

  108. def getRandBox(myList):
  109.     simpleLock=[]
  110.     simpleEmpty=[]
  111.     for [x,y,z] in myList:
  112.         simpleLock.append((y//100)*4+x//100)
  113.     simpleEmpty=[x for x in range(0,16) if x not in simpleLock]
  114.     import random
  115.     x=random.choice(simpleEmpty)
  116.     z = random.randint(0,10)
  117.     z = 2 if z <= 9 else 4
  118.     return  [(x%4)*100,(x//4)*100,z]

  119. def drawBox(box,border=None):
  120.     x,y,z=box

  121.     if(border==None):
  122.         border= color2
  123.     fillColor=colors[z if z<32768 else -1 ]

  124.     myRect=pygame.draw.rect(windowSurfaceObj,border,(x+2,y+2,98,98),0)
  125.     windowSurfaceObj.fill(border,myRect)
  126.     windowSurfaceObj.fill(fillColor, myRect.inflate(-5, -5))
  127.     msg=str(z)

  128.     msgSurfaceObj = fontObj.render(msg,True,granite if z<16 else whiteColor)
  129.     msgRectobj = msgSurfaceObj.get_rect()

  130.     msgRectobj.center = (x+50,y+52)
  131.     windowSurfaceObj.blit(msgSurfaceObj,msgRectobj)

  132. locked=[]
  133. new  = (getRandBox(locked))
  134. print ("first pick:",new)
  135. locked.append(new)
  136. action = None
  137. Total = 0
  138. while True:
  139.     windowSurfaceObj.fill(lightblue)
  140.     pygame.draw.lines(windowSurfaceObj,lighterblue,False,lineArray,2)

  141.     if len(locked)==1:
  142.         drawBox(locked[-1],gold)

  143.     for event in pygame.event.get():
  144.         if event.type == pygame.QUIT:
  145.             pygame.quit()
  146.         elif event.type == pygame.MOUSEMOTION:
  147.             mousex, mousey = event.pos
  148.             #soundObj.play()

  149.         elif event.type == pygame.KEYDOWN:
  150.             if event.key in (pygame.K_LEFT,pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN) :
  151.                 standStill=False

  152.                 print( "Arrow Key pressed.",event.key)
  153.                 action = event.key
  154.                 locked,standStill,score=processMovement(locked,event.key)

  155.                 if not standStill:
  156.                     Total = Total + score
  157.                     new =getRandBox(locked)   #get random box
  158.                     locked.append(new)       #append to locked
  159.                     print("random picK:",new)
  160.                     if(len(locked)==SIZE*SIZE):
  161.                         _,standStill1,_=processMovement(locked,pygame.K_RIGHT)
  162.                         _,standStill2,_=processMovement(locked,pygame.K_LEFT)
  163.                         _,standStill3,_=processMovement(locked,pygame.K_UP)
  164.                         _,standStill4,_=processMovement(locked,pygame.K_DOWN)
  165.                         _GameOver = standStill1 or standStill2 or standStill3 or standStill4


  166.             if event.key == pygame.K_a:
  167.                 msg = "'A'Key pressed"
  168.                 print("'A'Key pressed")
  169.             if event.key == pygame.K_ESCAPE:
  170.                 pygame.event.post(pygame.event.Event(pygame.QUIT))
  171.     if action:
  172.         for i in locked[:-1]:
  173.             drawBox(i,grey)

  174.         drawBox(locked[-1],gold)

  175.     pygame.display.update()
  176.     fpsClock.tick(30)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-7-13 23:05:56 | 显示全部楼层    本楼为最佳答案   
仅供参考:

搜狗截图20170713230459.png

  1. import pygame, sys
  2. from pygame.locals import *
  3. import pygame.locals
  4. from pygame import key,event

  5. pygame.init()
  6. fpsClock = pygame.time.Clock()
  7. SIZE = 4
  8. BLOCKSIZE=100
  9. MAX=SIZE*BLOCKSIZE
  10. _GameEnd=None
  11. _GameOver=None
  12. windowSurfaceObj = pygame.display.set_mode((MAX,MAX))
  13. pygame.display.set_caption('2048')

  14. redColor = pygame.Color(255,0,0)
  15. greenColor = pygame.Color(0,255,0)
  16. blueColor = pygame.Color(0,0,255)
  17. whiteColor = pygame.Color (255,255,255)
  18. lightblue = pygame.Color(173, 216, 230)
  19. lighterblue = pygame.Color(235,255,255)
  20. grey =  pygame.Color(145,141,142)
  21. gold =  pygame.Color(255,215,0)
  22. black=  pygame.Color(0,0,0)
  23. granite = pygame.Color(131,126,124)
  24. box1 =  pygame.Color(201,196,194)
  25. color2 =(229,228,227)
  26. color4 = pygame.Color(229,182,147)

  27. colors = {2:(229,228,227),4:(229,228-20,227-40),8:(229,228-30,227-60),16:(229,150,100),
  28.           32:(200,100,50),64:(150,60,30),128:(255,219,90),
  29.           256:(229,200,70),512:(229,180,50),1024:(229,170,40),2048:(229,160,20),
  30.           4096:(0,0,0),8192:(0,0,100),16384:(30,0,0),32768:(60,0,0)}
  31. mousex,mousey = 0,0

  32. fontObj  = pygame.font.SysFont('verdana',32)
  33. fontObj2  = pygame.font.SysFont('verdana',32)
  34. fontObj16  = pygame.font.SysFont('verdana',28)
  35. fontObj128  = pygame.font.SysFont('verdana',26,bold=True)
  36. fontObj1024  = pygame.font.SysFont('verdana',24,bold=True)
  37. fontObj16384  = pygame.font.SysFont('verdana',23,bold=True)
  38. fontObjSmall  = pygame.font.SysFont('verdana',22,bold=True)
  39. fonts =[fontObj2,fontObj16,fontObj128,fontObj1024,fontObj16384,fontObjSmall]

  40. # soundObj = pygame.mixer.Sound('bounce.wav')
  41. lineArray = []
  42. for a in range(BLOCKSIZE,MAX,BLOCKSIZE) :
  43.     lineArray.append( (0,a))
  44.     lineArray.append((MAX,a))
  45.     lineArray.append((MAX,a+BLOCKSIZE))
  46. lineArray.append((MAX,0))
  47. lineArray.append((0,0))
  48. for a in range(BLOCKSIZE,MAX,BLOCKSIZE) :
  49.     lineArray.append( (a,0))
  50.     lineArray.append((a,MAX))
  51.     lineArray.append((a+BLOCKSIZE,400))
  52. print(lineArray)

  53. def processMovement(myList:list,directive:int):

  54.     print(myList)
  55.     newList=[]
  56.     Matrix = [[0 for x in range(SIZE)] for x in range(SIZE)]
  57.     for (x,y,z) in myList:
  58.         Matrix[y//BLOCKSIZE][x//BLOCKSIZE]=z

  59.     if directive == pygame.K_DOWN:  # 90 rotation
  60.         Matrix=[list(elem) for elem in zip(*Matrix[::-1])]
  61.         Matrix,score=addMatrix(Matrix)
  62.         Matrix=[list(elem[::-1]) for elem in zip(*Matrix[::-1])][::-1]
  63.     if directive == pygame.K_UP:
  64.         Matrix=[list(elem) for elem in zip(*Matrix)]
  65.         Matrix,score=addMatrix(Matrix)
  66.         Matrix=[list(elem) for elem in zip(*Matrix)]

  67.     elif directive == pygame.K_LEFT:  # no rotation
  68.         print('move left, no rotation\n')
  69.         Matrix,score=addMatrix(Matrix)
  70.     elif directive == pygame.K_RIGHT:  # 180 rotation
  71.         print('move right, rotate 180\n')
  72.         Matrix=[each [::-1] for each in Matrix[::-1]]
  73.         Matrix,score=addMatrix(Matrix)
  74.         Matrix=[each [::-1] for each in Matrix[::-1]]

  75.     for j,line in enumerate(Matrix):
  76.         for i,each in enumerate(line):
  77.             if each!=0:
  78.                 newList.append([i*BLOCKSIZE,j*BLOCKSIZE,each])

  79.     standStill = True if sorted(myList)==sorted(newList) else False
  80.     return newList,standStill,score

  81. def addMatrix(myList:list):

  82.     newList=[]
  83.     newLine=[]
  84.     score=0
  85.     lastPaired=False
  86.     print("before add ",myList)
  87.     for i,line in enumerate(myList):
  88.         for i,each in enumerate(line):
  89.             print("loop:",i,each)
  90.             if each ==0:
  91.                 pass
  92.             elif len(newLine)>0 and newLine[-1]==each and not lastPaired:
  93.                 print("what is this:",each)
  94.                 newLine[-1]= 2*int(each)
  95.                 score=score+2*int(each)
  96.                 lastPaired=True
  97.                 if  each==1048 and _GameEnd==None : _GameEnd=True
  98.             else:
  99.                 lastPaired=False
  100.                 newLine.append(int(each))
  101.                 print("appending",i)
  102.         lastPaired=False

  103.         newLine.extend( [0] *(SIZE-len(newLine)))
  104.         print("add test:",len(newLine))
  105.         newList.append(newLine)
  106.         newLine=[]

  107.     return newList,score

  108. def getRandBox(myList):
  109.     simpleLock=[]
  110.     simpleEmpty=[]
  111.     for [x,y,z] in myList:
  112.         simpleLock.append((y//100)*4+x//100)
  113.     simpleEmpty=[x for x in range(0,16) if x not in simpleLock]
  114.     import random
  115.     x=random.choice(simpleEmpty)
  116.     z = random.randint(0,10)
  117.     z = 2 if z <= 9 else 4
  118.     return  [(x%4)*100,(x//4)*100,z]

  119. def drawBox(box,border=None):
  120.     x,y,z=box

  121.     if(border==None):
  122.         border= color2
  123.     fillColor=colors[z if z<32768 else -1 ]

  124.     myRect=pygame.draw.rect(windowSurfaceObj,border,(x+2,y+2,98,98),0)
  125.     windowSurfaceObj.fill(border,myRect)
  126.     windowSurfaceObj.fill(fillColor, myRect.inflate(-5, -5))
  127.     msg=str(z)

  128.     msgSurfaceObj = fontObj.render(msg,True,granite if z<16 else whiteColor)
  129.     msgRectobj = msgSurfaceObj.get_rect()

  130.     msgRectobj.center = (x+50,y+52)
  131.     windowSurfaceObj.blit(msgSurfaceObj,msgRectobj)

  132. locked=[]
  133. new  = (getRandBox(locked))
  134. print ("first pick:",new)
  135. locked.append(new)
  136. action = None
  137. Total = 0
  138. while True:
  139.     windowSurfaceObj.fill(lightblue)
  140.     pygame.draw.lines(windowSurfaceObj,lighterblue,False,lineArray,2)

  141.     if len(locked)==1:
  142.         drawBox(locked[-1],gold)

  143.     for event in pygame.event.get():
  144.         if event.type == pygame.QUIT:
  145.             pygame.quit()
  146.         elif event.type == pygame.MOUSEMOTION:
  147.             mousex, mousey = event.pos
  148.             #soundObj.play()

  149.         elif event.type == pygame.KEYDOWN:
  150.             if event.key in (pygame.K_LEFT,pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN) :
  151.                 standStill=False

  152.                 print( "Arrow Key pressed.",event.key)
  153.                 action = event.key
  154.                 locked,standStill,score=processMovement(locked,event.key)

  155.                 if not standStill:
  156.                     Total = Total + score
  157.                     new =getRandBox(locked)   #get random box
  158.                     locked.append(new)       #append to locked
  159.                     print("random picK:",new)
  160.                     if(len(locked)==SIZE*SIZE):
  161.                         _,standStill1,_=processMovement(locked,pygame.K_RIGHT)
  162.                         _,standStill2,_=processMovement(locked,pygame.K_LEFT)
  163.                         _,standStill3,_=processMovement(locked,pygame.K_UP)
  164.                         _,standStill4,_=processMovement(locked,pygame.K_DOWN)
  165.                         _GameOver = standStill1 or standStill2 or standStill3 or standStill4


  166.             if event.key == pygame.K_a:
  167.                 msg = "'A'Key pressed"
  168.                 print("'A'Key pressed")
  169.             if event.key == pygame.K_ESCAPE:
  170.                 pygame.event.post(pygame.event.Event(pygame.QUIT))
  171.     if action:
  172.         for i in locked[:-1]:
  173.             drawBox(i,grey)

  174.         drawBox(locked[-1],gold)

  175.     pygame.display.update()
  176.     fpsClock.tick(30)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-13 23:51:31 | 显示全部楼层
你用的是pygame吗,是的话就检测碰撞的块数字是否相同,相同就先将它们flip刷掉,然后画出新的块,大概思路是这样,记得用列表来处理
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2017-7-13 23:53:40 | 显示全部楼层

捕获小甲鱼一头

小甲鱼,我最近在看你的C教程,但是卡在配置centos上边,完全按教程来做,总是ping失败,百度各种方法都试过,没用哎。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-14 00:34:09 | 显示全部楼层
老甲鱼与小甲鱼 发表于 2017-7-13 23:53
捕获小甲鱼一头

小甲鱼,我最近在看你的C教程,但是卡在配置centos上边,完全按教程来做,总是ping失 ...

试试 ping www.baidu.com
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-14 11:07:29 | 显示全部楼层
小甲鱼 发表于 2017-7-14 00:34
试试 ping www.baidu.com

ping任何一个网站都不行,百度说是网络配置有问题,然后跟着百度的方法修改了几个文件,都没用,越搞越遭,结果又重装,还不行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-14 16:13:54 | 显示全部楼层

我原来也是想着用数字去做的,但是刚开始发现很难把数字方块设置成正方形,所以就用图片去做了,里面用到了精灵和编组,结果程序方块运动超级慢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-14 18:12:06 | 显示全部楼层
老甲鱼与小甲鱼 发表于 2017-7-14 11:07
ping任何一个网站都不行,百度说是网络配置有问题,然后跟着百度的方法修改了几个文件,都没用,越搞越遭 ...

建议重新发一个提问,然后贴一下网络链接设置的界面
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-14 18:13:08 | 显示全部楼层
zihuan_l 发表于 2017-7-14 16:13
我原来也是想着用数字去做的,但是刚开始发现很难把数字方块设置成正方形,所以就用图片去做了,里面用到 ...

用图片固然会简单些,但配置低的机器(比如树莓派)容易卡……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 23:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表