ผลต่างระหว่างรุ่นของ "สร้างเกมด้วย Pygame"

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
แถว 231: แถว 231:
 
             <span style="color:green;"><b>.draw(display)  # draw ball</b></span>
 
             <span style="color:green;"><b>.draw(display)  # draw ball</b></span>
  
== เพิ่มแรงโน้มถ่วง ==
+
== เพิ่มแรงโน้มถ่วงตามแนวดิ่ง ==
 +
ทำให้ลูกบอลเคลื่อนที่อยู่ภายใต้แรงโน้มถ่วงที่มีความเร่ง 100 จุด/วินาที<sup>2</sup>
 +
 
 +
class Ball(object):
 +
    <i>:</i>
 +
    def move(self, delta_t, display, players):
 +
        global score, game_over
 +
        <span style="color:green;"><b>self.vy += 100*delta_t</b></span>
 +
        self.x += self.vx*delta_t
 +
        self.y += self.vy*delta_t
  
 
== ตัวอย่างแนวคิดอื่น ๆ ==
 
== ตัวอย่างแนวคิดอื่น ๆ ==

รุ่นแก้ไขเมื่อ 09:41, 8 พฤศจิกายน 2557

วิกินี้เป็นส่วนหนึ่งของรายวิชา 01204223

Pygame เป็นโมดูลภาษาไพทอนที่ออกแบบมาเพื่อความสะดวกในการพัฒนาเกม วิกินี้ยกตัวอย่างการสร้างเกมอย่างง่ายที่อาศัยบอร์ดไมโครคอนโทรลเลอร์ในการควบคุมผู้เล่น

การเตรียมตัว

ติดตั้งไลบรารี Pygame

สำหรับระบบปฏิบัติการ Ubuntu Linux ใช้คำสั่ง apt-get ติดตั้งได้โดยตรง

sudo apt-get install python-pygame

ส่วนระบบปฏิบัตการ Mac OS X หรือระบบปฏิบัติการอื่น ๆ ให้ดาวน์โหลดตัวติดตั้งจากเว็บไซท์ http://pygame.org/download.shtml

เตรียมบอร์ดไมโครคอนโทรลเลอร์

บอร์ดไมโครคอนโทรลเลอร์ที่นำมาใช้เป็นตัวควบคุมผู้เล่นในวิกินี้ต้องถูกโปรแกรมเฟิร์มแวร์ให้สามารถอ่านค่าแสงผ่านพอร์ท USB ได้แล้ว ให้แน่ใจว่า

เกมตัวอย่าง: สควอช

เกมที่เราจะใช้เป็นตัวอย่างเรียกว่า Squash ดัดแปลงมาจากเกม Pong ที่เป็นคลาสสิคสุดฮิต ลักษณะการเล่นจะเป็นผู้เล่นตั้งแต่หนึ่งคนขึ้นไปตีลูกกระทบกำแพง และพยายามรับลูกที่สะท้อนกลับมาให้ได้

สนามแข่งสควอช
หน้าจอเกมสควอชต้นแบบที่สร้างด้วย Pygame

โค้ดต้นแบบ

ดาวน์โหลดโค้ดต้นแบบจากลิ้งค์ http://www.cpe.ku.ac.th/~cpj/204223/squash.py แล้วนำมาบันทึกไว้ในไดเรคตอรีเดียวกันกับโมดูล practicum.py และ peri.py ที่ได้มาจากการปฏิบัติตามขั้นตอนในวิกิ การติดต่อกับบอร์ด MCU ผ่าน USB ด้วย Arduino ทดลองรันโปรแกรมด้วยไพทอน

python squash.py

ควรปรากฏผลลัพธ์ดังรูปตัวอย่างข้างต้น เกมต้นแบบมีกติกาและการควบคุมดังนี้

  • มีผู้เล่นคนเดียว
  • ใช้ปุ่มลูกศรขึ้น/ลงเลื่อนไม้ตีของผู้เล่นเพื่อรับลูก
  • ทุกครั้งที่รับลูกได้จะได้คะแนนเพิ่ม 1 คะแนน
  • หากรับลูกพลาดและลูกกระทบกำแพงด้านซ้ายมือถือเป็นการจบเกม
  • กดปุ่ม ESC เพื่อออกจากเกมได้ตลอดเวลา

โครงสร้างคลาสของเกม

class diagram

ควบคุมผู้เล่นด้วยบอร์ดไมโครคอนโทรลเลอร์

import pygame
from pygame.locals import *
from practicum import findDevices
from peri import PeriBoard


class Player(object):

    THICKNESS = 10

    def __init__(self, board, pos=WINDOW_SIZE[1]/2, width=100, color=WHITE):
        self.width = width
        self.pos = pos
        self.color = color
        self.board = board

    def move(self):
        try:
            self.pos = self.board.getLight()
        except:
            pass


def main():
    :
    ball = Ball(speed=(200,50))
    board = PeriBoard(findDevices()[0])
    player = Player(board, color=pygame.Color('green'),pos=100)

    while not game_over:
        for event in pygame.event.get(): # process events
            if (event.type == QUIT) or \
               (event.type == KEYDOWN and event.key == K_ESCAPE):
                game_over = True

        if pygame.key.get_pressed()[K_UP]:
            player.pos -= 5
        elif pygame.key.get_pressed()[K_DOWN]:
            player.pos += 5

        display.fill(BLACK)  # clear screen
        display.blit(score_image, (10,10))  # draw score
        player.move()  # move player
        player.draw(display)  # draw player

โค้ดข้างต้นถือว่าต้องมีบอร์ดไมโครคอนโทรลเลอร์เสียบอยู่อย่างน้อยหนึ่งบอร์ดเสมอ

ลดการส่ายของไม้ตี

class Player(object):
    :
    def move(self):
        try:
            self.pos = self.board.getLight()
            self.pos = 0.9*self.pos + 0.1*self.board.getLight()
        except:
            pass

รองรับผู้เล่นหลายคน

FPS = 50
WINDOW_SIZE = (500,500)
BLACK = pygame.Color('black')
WHITE = pygame.Color('white')
GREY  = pygame.Color('grey')
PLAYER_COLORS = ('green','yellow','red','cyan')


def main():
    :
    ball = Ball(speed=(200,50))
    board = PeriBoard(findDevices()[0])
    player = Player(board, color=pygame.Color('green'),pos=100)
    players = []
    for i,dev in enumerate(findDevices()):
        color = PLAYER_COLORS[i % len(PLAYER_COLORS)]
        board = PeriBoard(dev)
        players.append(Player(board,color=pygame.Color(color),pos=100,width=150))

    while not game_over:
        :
        display.fill(BLACK)  # clear screen
        display.blit(score_image, (10,10))  # draw score

        player.move()
        player.draw(display)  # draw player
        for p in players:
            p.move()  # move player
            p.draw(display)  # draw player

        ball.move(1./FPS, display, player players)  # move ball
        ball.draw(display)  # draw ball
$ python
>>> data = ['a','b','c']
>>> list(enumerate(data))
[(0, 'a'), (1, 'b'), (2, 'c')]
>>> for i,x in enumerate(data):
...     print i,x
... 
0 a
1 b
2 c
>>>
class Ball(object):
    :
    def move(self, delta_t, display, player players):
        global score, game_over
        self.x += self.vx*delta_t
        self.y += self.vy*delta_t

        # player-hitting check
        if player.can_hit(self):
            score += 1
            render_score()
            self.vx = abs(self.vx) # bounce ball back
        for p in players:
            if p.can_hit(self):
                score += 1
                render_score()
                self.vx = abs(self.vx) # bounce ball back

ปรับความเร็วลูกเมื่อกระทบไม้ตี

เพื่อเพิ่มอรรถรสในการเล่น เมื่อผู้เล่นสามารถรับลูกได้ควรให้ลูกเพิ่มความเร็วให้มากขึ้น รวมถึงสุ่มให้ลูกกระดอนออกไปในทิศทางที่แตกต่างกัน

เพิ่มความเร็วลูกหลังถูกตี

class Ball(object):
    :
    def move(self, delta_t, display, players):
        :
        for p in players:
            if p.can_hit(self):
                score += 1
                render_score()
                self.vx = abs(self.vx) # bounce ball back
                self.vx = min(1.2*abs(self.vx),1000) # bounce ball back

ปรับให้ลูกกระดอนตามตำแหน่งที่ตกกระทบไม้ตี

class Ball(object):
   :
   def move(self, delta_t, display, players):
       :
       for p in players:
           if p.can_hit(self):
               score += 1
               render_score()
               self.vx = min(1.2*abs(self.vx),1000) # bounce ball back
               self.vy += (self.y-p.pos)*2

เพิ่มจำนวนลูก

เมื่อกด space bar ให้บอลลูกใหม่ปรากฏขึ้นที่กึ่งกลางหน้าจอ โดยสุ่มความเร็วต้นให้ลูกวิ่งไปในทิศทางขวามือที่ความเร็วแนวดิ่งต่าง ๆ กัน

from random import randrange
import pygame
from pygame.locals import *
from practicum import findDevices
from peri import PeriBoard
def main():
    :
    ball = Ball(speed=(200,50))
    balls = [Ball(speed=(100,randrange(-50,50)))]
    :
def main():
    :
    while not game_over:
        for event in pygame.event.get(): # process events
            if (event.type == QUIT) or \
               (event.type == KEYDOWN and event.key == K_ESCAPE):
                game_over = True
            if (event.type == KEYDOWN and event.key == K_SPACE):
                newBall = Ball(speed=(100,randrange(-50,50)))
                balls.append(newBall)
def main():
    :
    while not game_over:
        :
        ball.move(1./FPS, display, players)  # move ball
        ball.draw(display)  # draw ball
        for b in balls:
            b.move(1./FPS, display, players)  # move ball
            .draw(display)  # draw ball

เพิ่มแรงโน้มถ่วงตามแนวดิ่ง

ทำให้ลูกบอลเคลื่อนที่อยู่ภายใต้แรงโน้มถ่วงที่มีความเร่ง 100 จุด/วินาที2

class Ball(object):
    :
    def move(self, delta_t, display, players):
        global score, game_over
        self.vy += 100*delta_t
        self.x += self.vx*delta_t
        self.y += self.vy*delta_t

ตัวอย่างแนวคิดอื่น ๆ

  • ปรับให้เล่นแบบแข่งขันกันและคิดคะแนนแยกตามผู้เล่น
  • แยกให้ผู้เล่นอยู่ที่กำแพงด้านต่าง ๆ กันทั้งสี่ด้าน
  • สุ่มให้มีไอเท็มพิเศษปรากฏขึ้นเพื่อเพิ่ม/ลดความสามารถของผู้เล่นที่เก็บได้
  • เปลี่ยนรูปแบบการเล่นจากสควอชเป็นตะกร้อลอดห่วงเพื่ออนุรักษ์กีฬาพื้นบ้าน

เอกสารเพิ่มเติม