class Simulator(object): def __init__(self ,progs, visualizer,gwidth = 90, glength = 120 , gfriction = 1): self.cycle = Cycle() self.ground = Ground(glength , gwidth ,gfriction ) self.players =[] for i in range(2): for j in range(5): self.players.append(Player(self.ground, progs[i] , i , j , Vector( ((1.0*indexi[j]) * (gwidth / 2)) , (1.0*indexj[j]) * (glength / 2) * ((-1) ** (i)) ) )) #print >>sys.stderr, 'PLAYER %d, %d: %f, %f'%(i, j, self.players[j].pos.x, self.players[j].pos.y) #print >>sys.stderr, 'PLAYER %d, %d: %f, %f'%(i, j, indexi[j] * gwidth / 2, indexj[j] * glength / 2 * (-1) ** (i)) self.ball = Ball(self.ground) self.state = State(self.players , self.ball) self.referee = Referee(self.state) self.visualizer = visualizer def send_data(self): for i in range(10): self.visualizer.stdin.write(`int(self.state.players[i].pos.x)`+'\n') self.visualizer.stdin.write(`int(self.state.players[i].pos.y)`+'\n') #print >>sys.stderr, 'THIS IS RS, PLAYER %d: %d, %d'%(i, int(self.state.players[i].pos.x), int(self.state.players[i].pos.y)) self.visualizer.stdin.write(`int(self.state.ball.pos.x)`+'\n') self.visualizer.stdin.write(`int(self.state.ball.pos.y)`+'\n') self.visualizer.stdin.write(`self.state.game_state `+'\n') #def player_move(self, i , coefficient=1.0/100): # self.players[i].move(coefficient) def ball_move(self , coefficient=1.0/100): self.ball.move(coefficient) width = self.ground.width length = self.ground.length while True: x = self.ball.pos.x y = self.ball.pos.y if x <= width/2 and x >= -width/2 and y <= length/2 and y >= -length/2: break #print >>sys.stderr, 'BALL IS OUTSIDE GROUND, VELOCITY IS: %f, %f'%(self.ball.vel.x, self.ball.vel.y) if x>(width/2) : self.ball.vel.x= -self.ball.vel.x self.ball.pos.x= width-x #print >>sys.stderr, 'THE BALL WENT TOO RIGHT, NEW X: %f'%(self.ball.pos.x) if x<-(width/2) : self.ball.vel.x= -self.ball.vel.x self.ball.pos.x= -width-x #print >>sys.stderr, 'THE BALL WENT TOO LEFT, NEW X: %f'%(self.ball.pos.x) if y>(length/2) : self.state.update( self.referee.is_goal(self.ball , self.ground) ) self.ball.vel.y= -self.ball.vel.y self.ball.pos.y= length-y #print >>sys.stderr, 'THE BALL WENT TOO UP, NEW Y: %f'%(self.ball.pos.y) if y<(-(length/2)) : self.state.update( self.referee.is_goal(self.ball , self.ground) ) self.ball.pos.y= -length-y self.ball.vel.y=-self.ball.vel.y #print >>sys.stderr, 'THE BALL WENT TOO DOWN, NEW Y: %f'%(self.ball.pos.y) # def check_pos(self , coefficient=1.0/100): # a = range(10) # random.shuffle(a) # sizes = [i/20.0 for i in xrange(1, 11)] # random.shuffle(sizes) # for i in a: # temp_pos = self.players[i].pos # for j in range(10): # if( ( self.players[j].is_overlap(sizes[i], sizes[j], temp_pos) ) and (j!=i)): # self.players[i].move(-coefficient) # break def move(self): # for j in xrange(100): # for i in xrange(10): # self.player_move(i) # self.ball_move() # self.check_pos() #for t in xrange(steps_per_cycle): coefficient = 1.0/config.steps_per_cycle q = deque(self.players) if self.state.kicked: if self.ball.vel.len() < 4: self.ball.vel = Vector(2*random.choice([-1, 1]), 2*random.choice([-1, 1])) for t in xrange(config.steps_per_cycle): self.ball_move(coefficient) for p in self.players: p.rsteps = config.steps_per_cycle no_change = 0 #print >>sys.stderr, 'move called' #player_size = random.choice([0.3, 0.4, 0.5]) while len(q): c = q.popleft() #print >>sys.stderr, 'moving %d, %d, %d'%(c.team, c.number, c.rsteps) c.move(coefficient) c.rsteps-=1 change = True for other in self.players: if c==other: continue if c.is_overlap(config.player_size, config.player_size, other.pos): c.move(-coefficient) c.rsteps+=1 change = False break if change: no_change=0 else: no_change+=1 if c.rsteps: q.append(c) if no_change==20: #print >>sys.stderr, 'breaking' #for p in self.players: # print >>sys.stderr, 'PLAYER %d, %d: %f, %f'%(p.team, # p.number, # p.pos.x, # p.pos.y) #print >>sys.stderr, 'BALL: %f, %f'%(self.ball.pos.x, # self.ball.pos.y) break # while True: # change = False # for p in self.players: # if not p.rsteps: # continue # p.move(coefficient) # p.rsteps-=1 # change = True # for other in self.players: # if other==p: # continue # if p.is_overlap(config.player_size, config.player_size, # other.pos): # p.move(-coefficient) # change = False # break # if not change: # break def goto_kickoff(self): self.ball.pos = Vector(0, 0) self.ball.vel = Vector(0, 0) gwidth = config.gwidth glength = config.glength for i in xrange(2): for j in xrange(5): self.players[i*5+j].pos=Vector( ((1.0*indexi[j]) * (gwidth / 2)) , (1.0*indexj[j]) * (glength / 2) * ((-1) ** (i)) ) self.players[i*5+j].vel = Vector(0, 0) def simulate(self) : global cycle_length #print self.state.game_state prev_locs = [Vector(0, 0) for i in xrange(10)] for i in xrange(game_duration): #print >>sys.stderr, 'CYCLE #%d'%(i) self.state.kicked = False self.referee.update_state() self.send_data() #self.state.update() for j in xrange(10): self.players[j].comm.send_state(self.state) #print >>sys.stderr, 'DOOOOOOOOOOOOOOOOOOOOOOONE SENDING DATA AT %f'%(time.time()) time.sleep(cycle_length) self.cycle.update_players(self.state) self.move() soc = 0 for (i, p) in enumerate(self.players): soc += (p.pos-prev_locs[i]).len() if soc < 1 and self.state.game_state!=state.kickoff_team1 and self.state.game_state!=state.kickoff_team2: self.ball.vel += Vector(random.choice([-1, 1])*5, random.choice([-1, 1])*5) print 'accel' prev_locs = [Vector(p.pos.x, p.pos.y) for p in self.players] if self.state.game_state==state.team1_goal: self.state.game_state = state.kickoff_team2 self.goto_kickoff() if self.state.game_state==state.team2_goal: self.state.game_state = state.kickoff_team1 self.goto_kickoff() if(self.state.last_kicked != None): pass for i in xrange(10): self.players[i].comm.terminate()
class Game: WIDTH = 640 HEIGHT = 480 OFFSET = 20 clock = pygame.time.Clock() FPS = 200 def __init__(self, caption='Server'): pygame.init() pygame.font.init() self.paddle1 = PaddlePlayer(self.WIDTH, self.HEIGHT, self.OFFSET) # player self.paddle2 = PaddleEnemy(self.WIDTH, self.HEIGHT, self.WIDTH - 40) # bot self.b = Ball(self.WIDTH, self.HEIGHT) self.screen = pygame.display.set_mode((self.WIDTH, self.HEIGHT)) pygame.display.set_caption(caption) self.running = True self.font = pygame.font.SysFont('Arial', 30) self.local = False def handle_events(self): for event in pygame.event.get(): if event.type == QUIT: pygame.quit() self.running = 0 elif event.type == pygame.KEYDOWN: if event.key == pygame.K_UP: self.paddle1.KEYUP = True self.paddle1.direction = -1 elif event.key == pygame.K_DOWN: self.paddle1.KEYUP = True self.paddle1.direction = 1 elif event.type == pygame.KEYUP: if event.key == pygame.K_UP or event.key == pygame.K_DOWN: self.paddle1.KEYUP = False self.paddle1.direction = 0 def move_objects(self, autonomy=True): self.b.move(self.screen) self.paddle1.move(self.screen, self.b, autonomy=autonomy) self.paddle1.collision(self.b, self.screen) if self.local or autonomy: self.paddle2.move(self.screen, self.b) self.paddle2.collision(self.b, self.screen) def run(self, autonomy=True, move=True): if not self.running: return self.clock.tick(self.FPS) self.handle_events() if move: self.move_objects(autonomy) self.show() def show_background(self, width=10, height=20, gap=10): self.screen.fill(colors.get('gray')) lines = self.screen.get_height() // height color = colors.get('white') y = gap // 2 for i in range(lines): pygame.draw.rect( self.screen, color, (self.screen.get_width() // 2 - width, y, width, height)) y += height + gap def show_objects(self): self.b.show(self.screen) self.paddle1.show(self.screen) self.paddle2.show(self.screen) def draw_score(self): score1 = self.paddle2.score score2 = self.paddle1.score surface1 = self.font.render(str(score1), False, (0, 0, 0)) surface2 = self.font.render(str(score2), False, (0, 0, 0)) self.screen.blit(surface1, (self.screen.get_width() // 4, 0)) self.screen.blit(surface2, (self.screen.get_width() // 4 * 3 - 30, 0)) def show(self): self.show_background() self.show_objects() self.draw_score() pygame.display.flip() def move_player(self, value): self.paddle1.move_by_value(value, self.screen) def move_enemy(self, value): self.paddle2.move_by_value(value, self.screen) def get_info(self): game_info = { 'player_y': self.paddle1.y, 'enemy_y': self.paddle2.y, 'ball_pos': (self.b.x, self.b.y) } return game_info def update(self, game_info): print(type(game_info)) if type(game_info) == dict: self.paddle1.y = game_info['player_y'] self.paddle2.y = game_info['enemy_y'] self.b.x, self.b.y = game_info['ball_pos']
def main(): pygame.init() SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 SCALE = 80 # pixels per meter WIDTH = SCREEN_WIDTH/SCALE HEIGHT = SCREEN_HEIGHT/SCALE SCREEN_CENTRE = Point(WIDTH/2, HEIGHT/2) CENTRE = SCREEN_CENTRE/SCALE DISPLAY = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) CLOCK = pygame.time.Clock() totalTime = 0 GRAVITY = 9.81 helper = Helper(DISPLAY, SCALE, WIDTH, HEIGHT) drawPos = helper.drawPos worldPos = helper.worldPos drawVector = helper.drawVector personImage = pygame.image.load(os.getcwd()+"/person.jpg") personRect = personImage.get_rect() personImage = pygame.transform.scale(personImage, (int(personRect.width*(int(1.8*SCALE)/personRect.height)), int(1.8*SCALE))) moveData = { "lastPos": Point(), "currentPos": Point(CENTRE.x, 0), "lastScreenMousePos": Point(), "mouseHeld": False, "lastVelocity": Vector() } mouseVelocity = Vector() mouseBall = Ball() mouseBall.moveable = False tickerPoints = [] MAX_TICKER_POINTS = 100 TICKER_PERIOD = 0.02 timeSinceLastTicker = 0 ball = Ball() ball.setPos(Point(WIDTH/2, HEIGHT/2)) string = String() string.setConnections(mouseBall, ball) string.active = False while True: DISPLAY.fill(WHITE) deltaT = CLOCK.get_time()/1000 totalTime += deltaT moveData["lastPos"] = Point(moveData["currentPos"]) if not moveData["lastScreenMousePos"] == Point(pygame.mouse.get_pos()): moveData["currentPos"] = Point(worldPos(Point(pygame.mouse.get_pos()))) moveData["lastScreenMousePos"] = Point(pygame.mouse.get_pos()) heldKeys = pygame.key.get_pressed() for e in pygame.event.get(): if e.type == pygame.QUIT: pygame.quit() elif e.type == pygame.KEYDOWN: heldKeys = pygame.key.get_pressed() if (heldKeys[pygame.K_RCTRL] or heldKeys[pygame.K_LCTRL]) and\ (heldKeys[pygame.K_w] or heldKeys[pygame.K_q]): pygame.quit() if (heldKeys[pygame.K_SPACE]): mouseBallDist = moveData["currentPos"].distance(ball.pos) if mouseBallDist > 0: string.toggle() string.length = mouseBallDist elif e.type == pygame.MOUSEBUTTONDOWN: if e.button == 1: moveData["mouseHeld"] = True elif e.type == pygame.MOUSEBUTTONUP: if e.button == 1: moveData["mouseHeld"] = False keyboardMoveSpeed = 1 if heldKeys[pygame.K_a]: moveData["currentPos"] = moveData["currentPos"] - Point(keyboardMoveSpeed*deltaT, 0) elif heldKeys[pygame.K_d]: moveData["currentPos"] = moveData["currentPos"] + Point(keyboardMoveSpeed*deltaT, 0) if heldKeys[pygame.K_w]: moveData["currentPos"] = moveData["currentPos"] + Point(0, keyboardMoveSpeed*deltaT) elif heldKeys[pygame.K_s]: moveData["currentPos"] = moveData["currentPos"] - Point(0, keyboardMoveSpeed*deltaT) if deltaT > 0: moveData["lastVelocity"] = Vector(mouseBall.velocity) mouseVelocity = Vector(((moveData["currentPos"]-moveData["lastPos"])/deltaT).pos()) mouseAcceleration = (mouseVelocity - moveData["lastVelocity"])/deltaT else: mouseVelocity = Vector() mouseAcceleration = Vector() mouseBall.setPos(moveData["currentPos"]) mouseBall.setVelocity(mouseVelocity) #gravity adjustment if heldKeys[pygame.K_i]: GRAVITY = min(30.0,GRAVITY+0.1) elif heldKeys[pygame.K_k]: GRAVITY = max(0.0,GRAVITY-0.1) #ball radius if heldKeys[pygame.K_o]: ball.radius = min(4.0,ball.radius+0.01) elif heldKeys[pygame.K_l]: ball.radius = max(0.1,ball.radius-0.01) #string length if heldKeys[pygame.K_u]: string.length = min(8.0,string.length+0.01) elif heldKeys[pygame.K_j]: string.length = max(0.01,string.length-0.01) #reset all if heldKeys[pygame.K_r]: GRAVITY = 9.81 ball.radius = 0.1 string.length = 2.0 if ball.bottom <= 0: if ball.velocity.y < 0: ball.accelerate(Vector((0, -ball.velocity.y-ball.velocity.y*ball.cor))) else: ball.accelerate(Vector((0, -GRAVITY))*deltaT) #print(ball.velocity) if ball.left <= 0: if ball.velocity.x < 0: ball.accelerate(Vector((-ball.velocity.x-ball.velocity.x*ball.cor, 0))) if ball.right >= WIDTH: if ball.velocity.x > 0: ball.accelerate(Vector((-ball.velocity.x-ball.velocity.x*ball.cor, 0))) string.applyTension(deltaT) if moveData["mouseHeld"]: ball.setPos(moveData["currentPos"]) ball.setVelocity(mouseBall.velocity) ball.setInEquilibrium() else: ball.move(deltaT) string.correctPositions() # === DRAW # draw person DISPLAY.blit(personImage, (-(1/3)*personImage.get_rect().width, SCREEN_HEIGHT-personImage.get_rect().height)) # draw ticker tape if not moveData["mouseHeld"]: timeSinceLastTicker += deltaT if timeSinceLastTicker >= TICKER_PERIOD: tickerPoints.append(Point(ball.pos)) if len(tickerPoints) > MAX_TICKER_POINTS: del tickerPoints[0] timeSinceLastTicker = 0 else: tickerPoints = [] for p in tickerPoints: pygame.draw.circle(DISPLAY, BLUE, drawPos(p), 2, 2) # draw mouse velocity vector drawVector(mouseBall.velocity, moveData["currentPos"], 20, False, BLUE) # velocity vector is scaled so it can be more easily comprehended drawVector(ball.velocity, ball.pos, 10, False, GREEN, 1) # draw ball pygame.draw.circle(DISPLAY, RED, drawPos(ball.pos), int(ball.radius*SCALE), 1) if string.active: pygame.draw.line(DISPLAY, GREEN, drawPos(ball.pos), drawPos(moveData["currentPos"]), 1) font = pygame.font.SysFont("monospace", 15) # render text fps = font.render("{}fps".format(int(CLOCK.get_fps())), 1, BLACK) DISPLAY.blit(fps, (10, 10)) ballVelLabel = font.render("Ball velocity: {:.2f}ms-1".format(ball.velocity.mag), 1, BLACK) DISPLAY.blit(ballVelLabel, (10, 30)) mouseVelLabel = font.render("Mouse velocity: {:.2f}ms-1".format(mouseBall.velocity.mag), 1, BLACK) DISPLAY.blit(mouseVelLabel, (10, 50)) gravityVelLabel = font.render("Gravity: {:.2f}ms-2".format(GRAVITY), 1, BLACK) DISPLAY.blit(gravityVelLabel, (10, 70)) diameterVelLabel = font.render("Ball diameter: {:.2f}m".format(ball.radius*2), 1, BLACK) DISPLAY.blit(diameterVelLabel, (10, 90)) stringVelLabel = font.render("String length: {:.2f}m".format(string.length), 1, BLACK) DISPLAY.blit(stringVelLabel, (10, 110)) #control prompts stringConnect = font.render("Connect string: SPACE", 1, BLACK) DISPLAY.blit(stringConnect, (SCREEN_WIDTH-stringConnect.get_rect().width-10, 10)) stringControl = font.render("String length +/-: U/J", 1, BLACK) DISPLAY.blit(stringControl, (SCREEN_WIDTH-stringConnect.get_rect().width-10, 30)) gravityControl = font.render("Gravity +/-: I/K", 1, BLACK) DISPLAY.blit(gravityControl, (SCREEN_WIDTH-stringConnect.get_rect().width-10, 50)) diameterControl = font.render("Ball diameter +/-: O/L", 1, BLACK) DISPLAY.blit(diameterControl, (SCREEN_WIDTH-stringConnect.get_rect().width-10, 70)) resetAllControl = font.render("Reset all: R", 1, BLACK) DISPLAY.blit(resetAllControl, (SCREEN_WIDTH-stringConnect.get_rect().width-10, 90)) pygame.display.update() CLOCK.tick(120)
] brickRects = [] for brick in bricks: brickRects.append(brick.rect) #Main loop while 1: #Input handling for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() #Game logic if ball.rect.move(0, ball.speed[1]).collidelist(brickRects) > -1: ball.speed[1] = -ball.speed[1] ball.move([0, -ball.speed[1]]) elif ball.rect.move([ball.speed[0], 0]).collidelist(brickRects) > -1: ball.speed[0] = -ball.speed[0] ball.move([-ball.speed[0], 0]) ball.move(ball.speed) collide = ball.rect.collidelist(brickRects) if ball.rect.left < 0 or ball.rect.right > screenWidth: ball.speed[0] = -ball.speed[0] if ball.rect.top < 0 or ball.rect.bottom > screenHeight: ball.speed[1] = -ball.speed[1] if collide > -1: bricks.pop(collide) brickRects.clear()