Oop lab/arcade/snake

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
หน้านี้เป็นส่วนหนึ่งของ oop lab

จุดวิ่ง

ในส่วนแรกเราจะทำงูขนาด 1 ช่องวิ่งไปมาก่อน

เริ่มด้วยเกมว่าง ๆ

ก่อนเริ่ม อย่าลืมสร้าง git repository ไว้ที่ที่จะทำด้วย โดยสั่ง

git init

เราจะเริ่มโดยสร้างคลาส SnakeWindow ว่าง ๆ ไว้ก่อน ทั้งหมดนี้เขียนในไฟล์ snake.py

import arcade

SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600

class SnakeWindow(arcade.Window):
    def __init__(self, width, height):
        super().__init__(width, height)
 
        arcade.set_background_color(arcade.color.BLACK)

 
if __name__ == '__main__':
    window = SnakeWindow(SCREEN_WIDTH, SCREEN_HEIGHT)
    arcade.set_window(window)
    arcade.run()

ทดลองรัน

ถ้าทดลองรันได้ อย่าลืม git add snake.py แล้วก็

Gitmark.png commit งานด้วย!

sprite และ snake

เราจะใช้รูปด้านล่างขนาด 16 x 16 แทนตัวงู

Block.png

ดาวน์โหลดที่ [1] แล้วเซฟในโพลเดอร์ images ในชื่อ block.png

จากนั้นแก้ SnakeWindow ดังนี้

สร้าง arcade.Sprite ใน __init__

    def __init__(self, width, height):
        # ... ละบรรทัดอื่นไว้

        self.snake_sprite = arcade.Sprite('images/block.png')
        self.snake_sprite.set_position(300,300)

และสร้างเมท็อด on_draw มาวาด sprite

    def on_draw(self):
        arcade.start_render()

        self.snake_sprite.draw()

ทดลองรัน

ทดลองรัน ถ้าทำงานได้ อย่าลืมเพิ่มไฟล์รูป และ

Gitmark.png commit งานด้วย

World, Snake, และ ModelSprite

เราจะแยกโครงสร้างของคลาสในเกมแบบเดียวกับเกม space นั่นคือเราจะมี World เพื่อเก็บข้อมูลของเกมทั้งหมด คลาสงู (Snake) จะอยู่ใน world ส่วนที่แสดงผล ในขั้นแรกนี้เราจะใช้วิธีแบบเดิมคือจะสร้าง ModelSprite เพื่อแสดงงู แต่อีกหน่อยถ้างูยาวขึ้นได้เราจะใช้วิธีอื่น (แต่ ModelSprite ก็ยังจะมีประโยชน์อยู่ในการแสดงผลไม้)

ในส่วนนี้เราจะตัดและแก้จากโค้ด space เลย นิสิตควรจะพิจารณาโค้ดทั้งหมดและพยายามทำความเข้าใจว่าแต่ละส่วนทำงานประสานกันได้อย่างไรก่อนจะทำขั้นถัดไป

ไฟล์ models.py

class Snake:
    def __init__(self, world, x, y):
        self.world = world
        self.x = x
        self.y = y
 
    def update(self, delta):
        if self.x > self.world.width:
            self.x = 0
        self.x += 5


class World:
    def __init__(self, width, height):
        self.width = width
        self.height = height
 
        self.snake = Snake(self, width // 2, height // 2)
 
 
    def update(self, delta):
        self.snake.update(delta)

คลาส ModelSprite ใน snake.py ใส่ไว้ก่อน SnakeWindow

class ModelSprite(arcade.Sprite):
    def __init__(self, *args, **kwargs):
        self.model = kwargs.pop('model', None)
 
        super().__init__(*args, **kwargs)
 
    def sync_with_model(self):
        if self.model:
            self.set_position(self.model.x, self.model.y)
 
    def draw(self):
        self.sync_with_model()
        super().draw()

คลาส SnakeWindow ใน snake.py ที่แก้ไขแล้ว

class SnakeWindow(arcade.Window):
    def __init__(self, width, height):
        super().__init__(width, height)
 
        arcade.set_background_color(arcade.color.BLACK)

        self.world = World(SCREEN_WIDTH, SCREEN_HEIGHT)
        
        self.snake_sprite = ModelSprite('images/block.png',
                                        model=self.world.snake)
        self.snake_sprite.set_position(300,300)
        

    def update(self, delta):
        self.world.update(delta)
        
        
    def on_draw(self):
        arcade.start_render()

        self.snake_sprite.draw()

ทดลองรัน

ถ้าพบว่างูวิ่งเร็วมาก แปลว่าทำงานได้ ให้

Gitmark.png commit งานด้วย