ผลต่างระหว่างรุ่นของ "Oop lab/arcade/snake"
Jittat (คุย | มีส่วนร่วม) |
Jittat (คุย | มีส่วนร่วม) |
||
แถว 73: | แถว 73: | ||
เราจะแยกโครงสร้างของคลาสในเกมแบบเดียวกับเกม space นั่นคือเราจะมี World เพื่อเก็บข้อมูลของเกมทั้งหมด คลาสงู (Snake) จะอยู่ใน world ส่วนที่แสดงผล ในขั้นแรกนี้เราจะใช้วิธีแบบเดิมคือจะสร้าง ModelSprite เพื่อแสดงงู แต่อีกหน่อยถ้างูยาวขึ้นได้เราจะใช้วิธีอื่น (แต่ ModelSprite ก็ยังจะมีประโยชน์อยู่ในการแสดงผลไม้) | เราจะแยกโครงสร้างของคลาสในเกมแบบเดียวกับเกม space นั่นคือเราจะมี World เพื่อเก็บข้อมูลของเกมทั้งหมด คลาสงู (Snake) จะอยู่ใน world ส่วนที่แสดงผล ในขั้นแรกนี้เราจะใช้วิธีแบบเดิมคือจะสร้าง ModelSprite เพื่อแสดงงู แต่อีกหน่อยถ้างูยาวขึ้นได้เราจะใช้วิธีอื่น (แต่ ModelSprite ก็ยังจะมีประโยชน์อยู่ในการแสดงผลไม้) | ||
+ | |||
+ | ในส่วนนี้เราจะตัดและแก้จากโค้ด space เลย '''นิสิตควรจะพิจารณาโค้ดทั้งหมดและพยายามทำความเข้าใจว่าแต่ละส่วนทำงานประสานกันได้อย่างไรก่อนจะทำขั้นถัดไป''' | ||
+ | |||
+ | '''ไฟล์ <tt>models.py</tt>''' | ||
+ | <syntaxhighlight lang="python"> | ||
+ | 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) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | '''คลาส ModelSprite''' ใน <tt>snake.py</tt> ใส่ไว้ก่อน <tt>SnakeWindow</tt> | ||
+ | <syntaxhighlight lang="python"> | ||
+ | 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() | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | '''คลาส SnakeWindow''' ใน <tt>snake.py</tt> ที่แก้ไขแล้ว | ||
+ | <syntaxhighlight lang="python"> | ||
+ | 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() | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==== ทดลองรัน ==== | ||
+ | |||
+ | ถ้าพบว่างูวิ่งเร็วมาก แปลว่าทำงานได้ ให้ | ||
+ | |||
+ | {{gitcomment|commit งานด้วย}} |
รุ่นแก้ไขเมื่อ 21:20, 14 กันยายน 2560
- หน้านี้เป็นส่วนหนึ่งของ 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 แล้วก็
sprite และ snake
เราจะใช้รูปด้านล่างขนาด 16 x 16 แทนตัวงู
ดาวน์โหลดที่ [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()
ทดลองรัน
ทดลองรัน ถ้าทำงานได้ อย่าลืมเพิ่มไฟล์รูป และ
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()
ทดลองรัน
ถ้าพบว่างูวิ่งเร็วมาก แปลว่าทำงานได้ ให้