forth入門

gforthのインストール
Debian系のLinuxの場合
$ sudo apt install gforth

gforthの起動
$ gforth

gforthの終了
byeと入力するかCtrl+Dを押す

1 + 2 を計算する
1 2 + .s

1 + 2 * 3 を計算する
1 2 3 * + .s

(1 + 2) * (3 + 4)を計算する
1 2 + 3 4 + * .s

スタックの一番上の要素をコピーしてスタックに積む
1 2 3 ok
.s <3> 1 2 3 ok
dup ok
.s <4> 1 2 3 3 ok

スタックの1番目と2番目を交換する
1 2 3 ok
.s <3> 1 2 3 ok
swap ok
.s <3> 1 3 2 ok

スタックの3番目の要素を取り出し1番上に積む
1 2 3 ok
.s <3> 1 2 3 ok
rot ok
.s <3> 2 3 1 ok

ワードの定義
1を足すワード「inc」の定義
: inc 1 + ;
使用例
2 inc
2乗するワードの定義
: square dup * ;

Pygame入門 Sprite同士の衝突を検知して、そのSpriteを削除する

f:id:collatz:20220405170715g:plain
pygame.sprite.spritecollideでSprite同士の衝突を検知できる。
また、引数の指定によって、衝突したSpriteを削除できる。

pygame.sprite.spritecollide(sprite, group, dokill)
2番めの引数のgroupに属するSpriteのうち、
1番目の引数のspriteと衝突しているもののリストを返す。
3番めの引数のdokillをTrueにすると、衝突しているSpriteがgroupから削除される。
Spriteの衝突判定は、Spriteのrectプロパティによって行っている。

import pygame
import sys

SCREEN = pygame.Rect(0, 0, 400, 400)
FPS = 30

WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)

BALL_SIZE = 20

PADDLE_WIDTH = 60
PADDLE_HEIGHT = 20
PADDLE_POS_Y = SCREEN.bottom - PADDLE_HEIGHT * 2

class Ball(pygame.sprite.Sprite):
    def __init__(self, pos, speed):
        pygame.sprite.Sprite.__init__(self, self.containers)
        x, y = pos
        vx, vy = speed
        self.image = pygame.Surface((BALL_SIZE, BALL_SIZE))
        self.image.fill(WHITE)
        pygame.draw.circle(self.image, RED, self.image.get_rect().center, BALL_SIZE / 2)
        self.rect = pygame.Rect(x, y, BALL_SIZE, BALL_SIZE)
        self.vx = vx
        self.vy = vy

    def update(self):
        self.rect.move_ip(self.vx, self.vy)
        if self.rect.left < SCREEN.left or SCREEN.right < self.rect.right:
            self.vx = -self.vx
        if self.rect.top < SCREEN.top or SCREEN.bottom < self.rect.bottom:
            self.vy = -self.vy
        self.rect = self.rect.clamp(SCREEN)

class Paddle(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self, self.containers)
        self.image = pygame.Surface((PADDLE_WIDTH, PADDLE_HEIGHT))
        self.image.fill(GREEN)
        self.rect = pygame.Rect(0, PADDLE_POS_Y, PADDLE_WIDTH, PADDLE_HEIGHT)

    def update(self):
        self.rect.centerx = pygame.mouse.get_pos()[0] #Paddleの真ん中のX座標をマウスのX座標にする
        self.rect = self.rect.clamp(SCREEN) #SCREENから出ないようにする

#main()
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode(SCREEN.size)

sprite_group = pygame.sprite.Group() #すべてのスプライトの更新と描画を行うためのグループ
ball_group = pygame.sprite.Group() #Paddleとの衝突を調べるためのグループ

Ball.containers = sprite_group, ball_group
Paddle.containers = sprite_group

Ball((200, 200), (2, 3))
Ball((100, 200), (3, 3))
Ball((100, 300), (3, 4))
paddle = Paddle()

while True:
    #paddleと衝突したBallを削除する
    pygame.sprite.spritecollide(paddle, ball_group, True)

    screen.fill(WHITE)
    sprite_group.update()
    sprite_group.draw(screen)

    pygame.display.update()
    clock.tick(FPS)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

Pygame入門 ブロック崩しのパドルをスプライトで作る

スプライトの使い方

1.「pygame.sprite.Sprite」を継承してスプライトオブジェクトを作る

2.スプライトグループを作る

3.スプライトグループにスプライトオブジェクトを追加する

4.スプライトグループの更新を実行する

グループに追加されているスプライトオブジェクトのupdate()メソッドが実行される。

5.スプライトグループの描画を実行する

グループに追加されているスプライトオブジェクトのself.imageとself.rectの内容を使って描画される。
self.image(pygame.Surface型)によって描画される内容が決まる。
self.rect(pygame.Rect型)によって描画される位置が決まる。

マウスの位置によってパドルが左右に動くプログラム

import pygame
import sys

SCREEN = pygame.Rect(0, 0, 400, 400)
FPS = 30

WHITE = (255, 255, 255)
GREEN = (0, 255, 0)

PADDLE_WIDTH = 60
PADDLE_HEIGHT = 20
PADDLE_POS_Y = SCREEN.bottom - PADDLE_HEIGHT * 2

class Paddle(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((PADDLE_WIDTH, PADDLE_HEIGHT))
        self.image.fill(GREEN)
        self.rect = pygame.Rect(0, PADDLE_POS_Y, PADDLE_WIDTH, PADDLE_HEIGHT)

    def update(self):
        self.rect.left = pygame.mouse.get_pos()[0] #Paddleの左端をマウスのX座標にする
        self.rect = self.rect.clamp(SCREEN) #SCREENから出ないようにする


pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode(SCREEN.size)
paddle = Paddle() #スプライトオブジェクトの作成
sprite_group = pygame.sprite.Group() #スプライトグループの作成
sprite_group.add(paddle) #スプライトグループへスプライトオブジェクトを追加

while True:
    screen.fill(WHITE)
    sprite_group.update() #スプライトグループの更新
    sprite_group.draw(screen) #スプライトグループの描画

    pygame.display.update()
    clock.tick(FPS)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

Pygame入門 ブロック崩しのパドルをマウスで動かす

import pygame
import sys

SCREEN = pygame.Rect(0, 0, 400, 400)
FPS = 30

WHITE = (255, 255, 255)
GREEN = (0, 255, 0)

PADDLE_WIDTH = 60
PADDLE_HEIGHT = 20
PADDLE_POS_Y = SCREEN.bottom - PADDLE_HEIGHT * 2

pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode(SCREEN.size)
paddle = pygame.Surface((PADDLE_WIDTH, PADDLE_HEIGHT))
paddle.fill(GREEN)

while True:
    screen.fill(WHITE)

    PADDLE_POS_X = pygame.mouse.get_pos()[0]
    if PADDLE_POS_X > (SCREEN.right - PADDLE_WIDTH):
        PADDLE_POS_X = SCREEN.right - PADDLE_WIDTH
    screen.blit(paddle, (PADDLE_POS_X, PADDLE_POS_Y))

    pygame.display.update()
    clock.tick(FPS)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

Pygame入門 画像をSpriteにして動かす

import pygame
import sys

SCREEN = pygame.Rect(0, 0, 400, 400)
WHITE = (255, 255, 255)

class Ball(pygame.sprite.Sprite):
    def __init__(self, image_file, pos, speed):
        pygame.sprite.Sprite.__init__(self)
        x, y = pos
        vx, vy = speed
        self.image = pygame.image.load(image_file)
        w = self.image.get_width()
        h = self.image.get_height()
        self.rect = pygame.Rect(x, y, w, h)
        self.vx = vx
        self.vy = vy

    def update(self):
        self.rect.move_ip(self.vx, self.vy)
        if self.rect.left < SCREEN.left or SCREEN.right < self.rect.right:
            self.vx = -self.vx
        if self.rect.top < SCREEN.top or SCREEN.bottom < self.rect.bottom:
            self.vy = -self.vy
        self.rect = self.rect.clamp(SCREEN)

    def draw(self, surface):
        surface.blit(self.image, self.rect)

def main():
    pygame.init()
    screen = pygame.display.set_mode(SCREEN.size)
    ball = Ball('ball.png', (200, 200), (5, 10))
    clock = pygame.time.Clock()

    while True:
        clock.tick(30)
        screen.fill(WHITE)
        ball.update()
        ball.draw(screen)
        pygame.display.update()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

main()

実行結果

f:id:collatz:20220404163421g:plain

Pygame入門 画像を動かす

import pygame
import sys

SCREEN = pygame.Rect(0, 0, 400, 400)
FPS = 30
WHITE = (255, 255, 255)

def main():
    pygame.init()
    clock = pygame.time.Clock()
    screen = pygame.display.set_mode(SCREEN.size)

    ball = pygame.image.load('ball.png')
    ball_width = ball.get_size()[0]
    ball_height = ball.get_size()[1]
    ball_x = 100 #ballの初期x座標
    ball_y = 200 #ballの初期y座標
    ball_dx = 5 #ballのx座標移動量
    ball_dy = 5 #ballのy座標移動量

    while True:
        screen.fill(WHITE)
        screen.blit(ball, (ball_x, ball_y))

        #画面の左端か右端に移動したら、x座標の移動方向を変える
        if (ball_x < SCREEN.left) or (SCREEN.right - ball_width < ball_x):
            ball_dx *= -1

        #画面の上端か下端に移動したら、y座標の移動方向を変える
        if (ball_y < SCREEN.top) or (SCREEN.bottom - ball_height < ball_y):
            ball_dy *= -1

        #ballを移動させる
        ball_x += ball_dx
        ball_y += ball_dy

        pygame.display.update()
        clock.tick(FPS)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

if __name__ == '__main__':
    main()

Pygame入門 図形(四角)を動かす

import pygame
import sys

SCREEN_SIZE = (400, 400)
WHITE = (255, 255, 255)
RED   = (255,   0,   0)
FPS = 1

def main():
    pygame.init()
    clock = pygame.time.Clock()
    screen = pygame.display.set_mode(SCREEN_SIZE)
    ball = pygame.Rect(100, 100, 10, 10)

    while True:
        screen.fill(WHITE)
        pygame.draw.rect(screen, RED, ball)
        ball.move_ip(10, 0)
        pygame.display.update()
        clock.tick(FPS)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

if __name__ == '__main__':
    main()