読者です 読者をやめる 読者になる 読者になる

pygameでゲームのプロトタイプを

なんか急にコードどうでもよいプログラミングがしたくなったのでむかつくアイコンぶっ飛ばすゲーム作った.

#!/usr/bin/env python
#-*- coding:utf-8 -*-
import pygame
import pygame.locals
from pygame.locals import Rect
import random
import math
import sys

SCREEN_SIZE = (640, 480)

BACKGROUND = (0x7f, 0x7f, 0x7f)

class Controller:
 x = 0
 y = 0
 a = 0
 b = 0
 buttons = [False for i in range(16)]

con = Controller()

hitEffect = False

class Atack:
 def __init__(self, rect, direc, damage):
  self.rect = rect
  self.direc = direc
  self.damage = damage

class Player:
 vx, vy = 0.0, 0.0
 direc = 4
 secondJumpFlg = True
 x = SCREEN_SIZE[0] / 2
 y = SCREEN_SIZE[1] / 2
 hit = None
 gauge = 0
 def __init__(self, screen):
  self.screen = screen
 def update(self):
  atack = 0
  jump = 1
  smash = 2
  if not con.buttons[atack]:
   if con.x > 0.0:
    self.vx = min(self.vx + con.x * con.x * con.x * 2.5, con.x * 20.0)
    self.direc = 4
   elif con.x < 0.0:
    self.vx = max(self.vx + con.x * con.x * con.x * 2.5, con.x * 20.0)
    self.direc = -4
   if con.buttons[jump]:
    if self.y == SCREEN_SIZE[1] - 16 - 32:
     self.vy -= 12.0
     self.secondJumpFlg = False
    elif self.vy > -2.5 and not self.secondJumpFlg:
     self.vy -= 12.0 + self.vy
     self.secondJumpFlg = True
  self.vx *= 0.925
  self.vy = min(self.vy + 0.5, 5.0)
  self.x = min(SCREEN_SIZE[0], max(0, self.x + self.vx))
  if self.x == SCREEN_SIZE[0] or self.x == 0 and self.y > 0.0:
   self.vy = min(self.vy + 0.15, 2.5)
  else:
   self.vy += 0.0125
  if con.y > 0:
   self.vy += con.y
  self.y = min(SCREEN_SIZE[1] - 16 - 32, self.vy + self.y)
  if self.y == SCREEN_SIZE[1] - 16 - 32:
   self.vy = 0.0
  self.hit = None
  if con.buttons[atack]:
   if con.y < -0.5:
    hitRect = (int(self.x) - 24, int(self.y) - 48, 48, 24)
   elif con.y > 0.5:
    hitRect = (int(self.x) - 32, int(self.y) + 8, 64, 16)
   elif self.direc > 0:
    hitRect = (int(self.x) + self.direc, int(self.y) - 8, 48, 24)
   elif self.direc < 0:
    hitRect = (int(self.x) + self.direc - 48, int(self.y) - 8, 48, 24)
   pygame.draw.ellipse(self.screen, (255, 0, 255), hitRect)
   self.hit = Atack(hitRect, (con.x * 10, min(con.y, -0.5) * 7.5), 1)
  elif con.buttons[smash] and self.gauge >= 80:
   if con.y < -0.5:
    hitRect = (int(self.x) - 24, int(self.y) - 48, 48, 24)
   elif con.y > 0.5:
    hitRect = (int(self.x) - 32, int(self.y) + 8, 64, 16)
   elif self.direc > 0:
    hitRect = (int(self.x) + self.direc, int(self.y) - 8, 48, 24)
   elif self.direc < 0:
    hitRect = (int(self.x) + self.direc - 48, int(self.y) - 8, 48, 24)
   pygame.draw.ellipse(self.screen, (255, 255, 0), hitRect)
   self.hit = Atack(hitRect, (con.x * 100, min(con.y - 0.5, -0.4)  * 100), 10)
   self.gauge -= 80
  self.screen.fill*1
  pygame.draw.circle(self.screen, (255, 255, 255), (int(self.x) + self.direc, int(self.y) - 20), 2)

class Enemy:
 vx, vy = 0.0, 0.0
 damage = 0
 def __init__(self, screen, x, y=SCREEN_SIZE[1]/2):
  self.screen = screen
  self.x = x
  self.y = y
  self.direc = random.choice*2
 def update(self, player):
  global hitEffect
  if abs(self.vx) < 0.5:
   self.vx += self.direc / abs(self.direc) * 0.5
  self.vx *= 0.925
  self.vy = min(self.vy + 0.5, 5.0)
  self.x = min(SCREEN_SIZE[0], max(0, self.x + self.vx))
  self.y = max(-640, min(SCREEN_SIZE[1] - 16 - 16, self.vy + self.y))
  if self.y == -640:
   self.vy *= -1
  if self.x == SCREEN_SIZE[0] or self.x == 0:
   self.vx *= -1
   self.direc *= -1
  if self.y == SCREEN_SIZE[1] - 16 - 16:
   self.vy = 0.0
  pygame.draw.rect(self.screen, (0x40, 0x40, 0x40), Rect(self.x - 16, self.y - 16, 32, 32), 3)
  pygame.draw.circle(self.screen, (0x40, 0x40, 0x40), (int(self.x) + self.direc + 4, int(self.y) - 8), 4, 4)
  pygame.draw.circle(self.screen, (0x40, 0x40, 0x40), (int(self.x) + self.direc - 4, int(self.y) - 8), 4, 4)
  if player.hit:
   hitRect = player.hit.rect
   r = Rect(self.x - 16, self.y - 16, 32, 32)
   if r.colliderect(hitRect):
    dx = player.hit.direc[0] + (self.x - player.x) / max(0.01, abs(player.x - self.x))
    dy = min(-1.0, player.hit.direc[1])
    self.vx += dx * self.damage ** 0.5 / 10
    self.vy += dy * self.damage ** 0.5 / 10
    if math.hypot(self.vx, self.vy) > 32.0:
     hitEffect = True
    else:
     hitEffect = False
    self.damage += player.hit.damage
    player.gauge += player.hit.damage


class Test:
 def __init__(self, screen):
  self.screen = screen
  self.player = Player(screen)
  self.another = Player(screen)
  self.enemy = [Enemy(screen, random.randint(32, SCREEN_SIZE[1] - 32)) for i in range(16)]
 def update(self):
  pygame.draw.line(self.screen, (0, 0, 0), (0, SCREEN_SIZE[1] - 16), (SCREEN_SIZE[0], SCREEN_SIZE[1] - 16))
  self.player.update()
  for e in self.enemy:
   e.update(self.player)
  self.screen.fill*3
  return self

class Title:
 def __init__(self, screen):
  self.screen = screen
 def update(self):
  if con.x > 0:
   self.screen.fill*4
  else:
   self.screen.fill*5
  if con.a > 0:
   self.screen.fill*6
  else:
   self.screen.fill*7
  if con.y > 0:
   self.screen.fill*8
  else:
   self.screen.fill*9
  if con.b > 0:
   self.screen.fill*10
  else:
   self.screen.fill*11
  for x in range(16):
   pygame.draw.rect(self.screen, (0, 0, 255), Rect(50 + 15 * x, 50, 10, 10), 1 if con.buttons[x] else 0)
  if con.buttons[0]:
   return Test(self.screen)
  return self

def main():
 global hitEffect
 pygame.init()
 screen = pygame.display.set_mode(SCREEN_SIZE)
 pygame.display.set_caption("testgame")
 pygame.joystick.init()
 try:
  joystick = pygame.joystick.Joystick(0) # create a joystick instance
  joystick.init() # init instance
  print 'Joystickの名称: ' + joystick.get_name()
  print 'ボタン数 : ' + str(joystick.get_numbuttons())
 except pygame.error:
  print 'Joystickが見つかりませんでした。'
  joystick = None
 
 currentScene = Title(screen)
 while True:
  if joystick:
   for event in pygame.event.get():
    if event.type == pygame.locals.QUIT:
     return 0
    elif event.type == pygame.locals.JOYAXISMOTION:
     con.x = joystick.get_axis(0)
     con.y = joystick.get_axis(1)
     con.a = joystick.get_axis(4)
     con.b = joystick.get_axis(3)
    elif event.type == pygame.locals.JOYBUTTONDOWN:
     con.buttons[event.button] = True
    elif event.type == pygame.locals.JOYBUTTONUP:
     con.buttons[event.button] = False
  else:
   pressed_keys = pygame.key.get_pressed()
   con.x = 0.0
   con.y = 0.0
   if pressed_keys[pygame.locals.K_LEFT]:
    con.x = -1.0
   if pressed_keys[pygame.locals.K_RIGHT]:
    con.x = 1.0
   if pressed_keys[pygame.locals.K_UP]:
    con.y = -1.0
   if pressed_keys[pygame.locals.K_DOWN]:
    con.y = 1.0
   for i, v in enumerate([pygame.locals.K_z, pygame.locals.K_x, pygame.locals.K_c, pygame.locals.K_v]):
    con.buttons[i] = pressed_keys[v]
   for event in pygame.event.get():
    if event.type == pygame.locals.QUIT:
      return 0
  screen.fill(BACKGROUND)
  next = currentScene.update()
  if next != currentScene:
   currentScene = next
  pygame.display.flip()
  if hitEffect:
   hitEffect = False
   pygame.time.wait(200)
  pygame.time.wait(15)
 return 0

if __name__ == '__main__':
 sys.exit(main())

ヒットストップするようにしたので,当たった感あると思う.
たったコレだけでジョイスティックも対応したゲーム作れるしとてもよいと思う.

ネイティブな言語で書くのは面倒なので,こういうのでプロトタイピングしてから書くと非常に良いと思う.

*1:0, 0, 0), Rect(self.x - 8, self.y - 32, 16, 64

*2:4, -4

*3:0, 0, 255), Rect(0, 10, self.player.gauge, 20

*4:255, 0, 0), Rect(300, 10, 100 * con.x, 20

*5:255, 0, 0), Rect(300 + 100 * con.x, 10, - 100 * con.x, 20

*6:127, 0, 0), Rect(300, 30, 100 * con.a, 20

*7:127, 0, 0), Rect(300 + 100 * con.a, 30, - 100 * con.a, 20

*8:0, 255, 0), Rect(10, 300, 20, 100 * con.y

*9:0, 255, 0), Rect(10, 300 + 100 * con.y, 20, - 100 * con.y

*10:0, 127, 0), Rect(30, 300, 20, 100 * con.b

*11:0, 127, 0), Rect(30, 300 + 100 * con.b, 20, - 100 * con.b