ゲーム概要
・spaceキー押下でゲーム開始
・ゲーム開始まで「Press 'SPACE' to start」とscoreを表示
・ランダムで矢が上から降る。その矢がパドルに当たるとゲームオーバー
・ブロックにはbc(破壊するためにボールを当てる回数)を設定
・ブロックにボールが当たるとスコアが加算
・ブロックの上下左右にボールが当たる。
・パドルにはMULTI_BALL_COUNTという定数で定めた回数ごとに一個ボールを発生させる。ボールの数がBALL_MAX_NUMに達している場合には発生しない。
・最後のボールが底につくとゲームオーバー
・パドルはボールが一回当たるごとに色が変化。
・全ブロックの破壊でClear!と表示
###ソースコード
from tkinter import * from dataclasses import dataclass import time import random import math DURATION=0.001 SPEAR_WIDTH=1 SPEAR_HEIGHT=40 SPEAR_COLOR="red" PADDLE_Y0=400 MULTI_BALL_COUNT=5 BALL_MAX_NUM=3 PAD=10 BOX_MARGIN=50 BOX_TOP_X=BOX_MARGIN BOX_TOP_Y=BOX_MARGIN BOX_WIDTH=700 BOX_HEIGHT=500 BOX_CENTER=BOX_TOP_X+BOX_WIDTH/2 CANVAS_WIDTH=BOX_TOP_X+BOX_WIDTH+BOX_MARGIN CANVAS_HEIGHT=BOX_TOP_Y+BOX_HEIGHT+BOX_MARGIN CANVAS_BACKGROUND="white" tk=Tk() tk.title("Game") canvas=Canvas(tk,width=CANVAS_WIDTH,height=CANVAS_HEIGHT,bg=CANVAS_BACKGROUND) canvas.pack() BALL_X0=0 BALL_Y0=BOX_TOP_X+BOX_HEIGHT/2 BALL_VX=4 BALL_VY=4 BLOCK_X=60 BLOCK_Y=80 BLOCK_W=100 BLOCK_H=40 BLOCKCOUNT=3 BLOCK_COLOR="blue" NUM_BLOCKS=4 COLORS=["blue","red","green","yellow","brown","gray"] VX0=[3,4,5,7] ADD_SCORE=10 @dataclass class MovingObject: id:int x:int y:int w:int h:int vx:int vy:int def move(self): self.x+=self.vx self.y+=self.vy def redraw(self): canvas.coords(self.id,self.x,self.y, self.x+self.w,self.y+self.h) class Paddle(MovingObject): def __init__(self,id,x,y,w,h): super().__init__(id,x,y,w,h,0,0) def set_v(self,v): self.vx=v def stop(self): self.vx=0 def change_paddle_color(self,c="red"): canvas.itemconfigure(pad.id,fill=c) canvas.itemconfigure(pad.id,outline=c) paddle.redraw() class Ball(MovingObject): def __init__(self,id,x,y,d,vx,vy): super().__init__(id,x,y,d,d,vx,vy) self.d=d class Block(MovingObject): def __init__(self,id,x,y,w,h,bc,c): super().__init__(id,x,y,w,h,0,0) self.bc=bc def delete(self): canvas.delete(self.id) class Spear(MovingObject): def __init__(self,id,x,y,w,h,vy,c): super().__init__(id,x,y,w,h,0,vy) def delete(self): canvas.delete(spear.id) @dataclass class Game: start:int def game_end(self,message): self.run=False canvas.create_text(BOX_CENTER,MESSAGE_Y,text=messge, font=('FixedSys',16)) tk.update() @dataclass class Box: west:int north:int east:int south:int balls:list paddle:Paddle blocks:list paddle_v:int duration:float run:int score:int paddle_count:int spear:Spear def __init__(self,x,y,w,h,duration): self.west,self.north=(x,y) self.east,self.south=(x+w,y+h) self.balls=[] self.paddle=None self.block=None self.spear=None self.blocks=[] self.duration=duration self.paddle_v=5 self.run=False self.score=0 self.paddle_count=0 def make_ball(self,x,y,d,vx,vy): id=canvas.create_oval(x,y,x+d,y+d, fill="black",outline="black") return Ball(id,x,y,d,vx,vy) def make_walls(self): canvas.create_rectangle(self.west,self.north,self.east,self.south) def check_wall(self,ball,game): if ball.x+ball.vx<=self.west or ball.x+ball.d+ball.vx>=self.east: ball.vx=-ball.vx if ball.y+ball.vy<=self.north: ball.vy=-ball.vy return False if ball.y+ball.d+ball.vy>=self.south: return True def set(self,n): self.make_walls() self.ball=self.make_ball(BOX_CENTER,PADDLE_Y0-50,10,BALL_VX,BALL_VY) self.paddle=self.make_paddle(self.east/2-50,PADDLE_Y0, 100,20, "green") for x in range(n): block=self.make_block(BLOCK_X+(BLOCK_W+PAD)*x,BLOCK_Y,BLOCK_W,BLOCK_H, BLOCKCOUNT,BLOCK_COLOR) self.blocks.append(block) canvas.bind_all("<KeyPress-Left>",self.left_paddle) canvas.bind_all("<KeyPress-Right>",self.right_paddle) canvas.bind_all("<KeyRelease-Left>",self.stop_paddle) canvas.bind_all("<KeyRelease-Right>",self.stop_paddle) canvas.bind_all('<KeyPress-space>',self.game_start) def make_paddle(self,x,y,w,h,c): id=canvas.create_rectangle(x,y,x+w,y+h, fill=c,outline=c) return Paddle(id,x,y,w,h) def check_paddle(self,ball,paddle): hit=False if(paddle.y+paddle.h>=ball.y+ball.d+ball.vy>=paddle.y and paddle.x<=ball.x+ball.d/2+ball.vx<=paddle.x+paddle.w): paddle.change_paddle_color(paddle,random.choice(COLORS)) ball.vy=-ball.vy ball.vx=int(10*(ball.x+ball.d/2-paddle.x)/paddle.w)-5 elif((paddle.x+paddle.w>=ball.x+ball.d+ball.vx>=paddle.x or paddle.x+paddle.w>=ball.x+ball.vx>=paddle.x) and paddle.y<=ball.y+ball.d/2+ball.vy<=paddle.y+paddle.h): paddle.change_paddle_color(paddle,random.choice(COLORS)) ball.vx=-ball.vx if hit: self.paddle_count+=1 if self.paddle_count%MULTI_BALL_COUNT==0: if len(self.balls)<BALL_MAX_NUM: ball=self.create_ball( BALL_X0, BALL_Y0,10, random.choice(VX0), BALL_VY ) slf.balls.apeend(ball) self.movingObjs.append(ball) def left_paddle(self,event): self.paddle.set_v(-self.paddle_v) def right_paddle(self,event): self.paddle.set_v(self.paddle_v) def stop_paddle(self,event): self.paddle.stop() def game_start(self,event): self.run=True def make_block(self,x,y,w,h,bc,c): id=canvas.create_rectangle(x,y,x+w,y+h, fill=c,outline=c) return Block(id,x,y,w,h,bc,c) def check_blocks(self,ball,block): if(block.y<=ball.y+ball.d/2<=block.y+block.h and ball.x+ball.vx<=block.x+block.w): ball.vx=-ball.vx score+=ADD_SCORE canvas.itemconfigure(id_score,text="score:"+str(self.score)) block.bc-=1 elif(block.x<=ball.x+ball.d/2<=block.x+block.w and(block.y<=ball.y<=block.y+block.h or block.y<=ball.y+ball.d<=block.y+block.h)): ball.vy=-ball.vy score+=ADD_SCORE canvas.itemconfigure(id_score,text="score:"+str(self.score)) block.bc-=1 if block.bc==0: delete_block(block) blocks.remove(block) return True def make_spear(self,x,y,w=SPEAR_WIDTH,h=SPEAR_HEIGHT,c=SPEAR_COLOR): id=canvas.create_rectangle(x,y,x+w,y+h,fill=c,outline=c) return Spear(id,x,y,w,h,SPEAR_VY,c) def check_spear(self,spear,paddle): if(paddle.x<=spear.x<=paddle.x+paddle.w and spear.y+spear.h>=paddle.y and spear.y<=paddle.y+paddle.h): return True else: return False def clear(self,blocks): if len(blocks)==0: canvas.create_text(BOX_CENTER,200,text="Clear!", font=('FixedSys',16)) def wait_start(self): id_score=canvas.create_text(10,10,text=("score:"+str(self.score)), font=("FixedSys",16), justify="left",anchor=NW) id_text=canvas.create_text(BOX_CENTER,200,text="Press 'SPACE' to start", font=('FixedSys',16)) tk.update() while not self.game_start: tk.update() time.sleep(DURATION) canvas.delete(id_text) tk.update() def animate(self): self.movingObjs=[self.paddle]+self.balls while self.run==True: for obj in self.movingObjs: obj.move() for ball in self.balls: if self.check_wall(ball): canvas.delete(ball.id) self.balls.remove(ball) self.movingObjs.remove(ball) if len(balls)==0: self.game_end("Game Over") break self.check_paddle(self.ball,self.paddle) for obj in self.movingObjs: obj.redraw() for block in self.blocks: self.check_blocks(self.ball,block) block.redraw() if self.spear: if self.check_spear(self.spear,self.paddle): self.game_end("Game Over") break if self.spear==None and random.random()<0.005: self.spear=self.make_spear( random.randint(self.west,self.east), self.north) self.movingObjs.append(self.spear) if self.spear and self.spear.y+self.spear.h>=self.south: canvas.delete_spear(self.spear.id) self.movingObjs.remove(self.spear) self.spear=None for obj in self.movingObjs: obj.redraw() self.clear(self.blocks) break time.sleep(self.duration) tk.update() box=Box(BOX_TOP_X,BOX_TOP_Y,BOX_WIDTH,BOX_HEIGHT,DURATION) box.set(NUM_BLOCKS) box.wait_start() box.animate()
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。