iaojfkojgpakm
@iaojfkojgpakm (ai ueo)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

imageとブロックを同時に動かしたい

Q&A

Closed

解決したいこと

playerとphoto_imgをキー入力によって同時に動かしたいです。
今はplayerだけが動いてphoto_imgはそのままです

例)
python tkinterでマリオゲームを作っています。

該当するソースコード


import tkinter as tk
import tkinter.messagebox as tmsg
import pygame
from PIL import Image, ImageTk



class Game:
    def __init__(self, root):
        self.root = root
        self.canvas = tk.Canvas(root, width=1500, height=800, bg="SteelBlue2")
        self.canvas.pack()



        self.player = self.canvas.create_rectangle(1470, 305, 1500, 340, fill='blue')
        

        self.blocks = [
            #1面
            self.canvas.create_rectangle(1500, 350, 480, 400, fill='DarkGoldenrod3', outline=""),#土台1
            self.canvas.create_rectangle(1500, 375, 480, 377, fill='DarkGoldenrod4', outline=""),#土台横1
         
            ]
        
        self.pakkunn = [self.canvas.create_rectangle(1330, 310, 1300, 350, fill='pink', outline=""),#パックン1
                       
        ]


    

        self.canvas.bind_all("<KeyPress>", self.move_player)
        self.moving = False
        
        self.continuous_fall()
        
        self.check_collision_pakkunn()

        self.mario_picture_show()

    def move_player(self, event):
        key = event.keysym
        if key == 'Left':
            self.move(-10, 0)
        elif key == 'Right':
            self.move(10, 0)
        elif key == 'Up' and not self.moving:
            self.jump_sound()
            self.moving = True
            self.move_up(0)
        elif key == 'Down':
            self.move(0, 10)
       
    def move(self, dx, dy):
        self.canvas.move(self.player, dx, dy)
        if self.check_collision() or self.wakugai():
            self.canvas.move(self.player, -dx, -dy)
            #self.canvas.move(photo_img, -dx, -dy)
        self.check_goal()
        self.go_to_hole()

     
    
    def move_up(self, step):
        if step < 100:
            self.move(0, -2)
            self.root.after(10, self.move_up, step + 1)
        else:
            self.move_down(0)
    
    def move_down(self, step):
        if step < 100:
            self.move(0, 2)
            self.root.after(5, self.move_down, step + 1)
        else:
            self.moving = False
    
    def check_collision(self):
        player_coords = self.canvas.coords(self.player)
        for block in self.blocks:
            block_coords = self.canvas.coords(block)

            if (player_coords[2] > block_coords[0] and player_coords[0] < block_coords[2] and
                player_coords[3] > block_coords[1] and player_coords[1] < block_coords[3]):
                return True
        return False

    def wakugai(self):
        player_coords = self.canvas.coords(self.player)
        return (player_coords[0] < 0 or player_coords[2] > 1500 )
    
    def continuous_fall(self):
        if not self.check_collision():
            self.move(0, 5)
        self.root.after(100, self.continuous_fall)
    
    def draw_cloud(self, canvas, x, y, width, height):
        # 楕円を重ねて雲を描く
        self.canvas.create_oval(x, y, x + width / 2, y + height / 2, fill='white', outline='white')
        self.canvas.create_oval(x + width / 4, y - height / 4, x + 3 * width / 4, y + height / 4, fill='white', outline='white')
        self.canvas.create_oval(x + width / 2, y, x + width, y + height / 2, fill='white', outline='white')
        self.canvas.create_oval(x + width / 6, y + height / 6, x + 5 * width / 6, y + 5 * height / 6, fill='white', outline='white')

    def check_goal(self):
        player_coords = self.canvas.coords(self.player)
        if player_coords[0] == 1200 and 550 <= player_coords[1] <= 725:
            self.goal_sound()
            tk.messagebox.showinfo("", "クリア!!")
            root.destroy()

    def go_to_hole(self):
        player_coords = self.canvas.coords(self.player)
        if (420 <=player_coords[0] <= 480 and player_coords[1] == 350) or (150 <=player_coords[0] <= 210 and player_coords[1] == 350) or (480 <=player_coords[0] <= 540 and player_coords[1] == 750):
            self.death_sound()
            tk.messagebox.showinfo("", "失敗")
            root.destroy()

        
    def death_sound(self):
        pygame.mixer.music.load("mario_death.mp3")
        pygame.mixer.music.play()

    def jump_sound(self):
        pygame.mixer.init()
        pygame.mixer.music.load("mario_jump.mp3")
        pygame.mixer.music.play()

    def goal_sound(self):
        pygame.mixer.music.load("mario_goal.mp3")
        pygame.mixer.music.play()



    def check_collision_pakkunn(self):
        player_coords = self.canvas.coords(self.player)
        for pakkunn in self.pakkunn:
            pakkunn_coords = self.canvas.coords(pakkunn)
            if (pakkunn_coords[2] > player_coords[0] and pakkunn_coords[0] < player_coords[2] and
                pakkunn_coords[3] > player_coords[1] and pakkunn_coords[1] < player_coords[3]):
                self.death_sound()
                tmsg.showinfo("", "死亡") 
                root.destroy()
                return
        self.root.after(100, self.check_collision_pakkunn)  # 定期的に呼び出して継続的にチェック

    def mario_picture_show(self):

        global img, photo_img
 
        # キャンバス作成
        canvasM = tk.Canvas(root, bg="SteelBlue2", height=38, width=35, highlightthickness=0)
        # キャンバス表示
        canvasM.place(x=1466, y=312)#(x=1465, y=307)
 
        # イメージ作成
        img = Image.open("mario.png")
        resized_image = img.resize((38, 40), Image.ANTIALIAS)
        photo_img = ImageTk.PhotoImage(resized_image)
        # キャンバスにイメージを表示
        canvasM.create_image(0, 0, image=photo_img, anchor=tk.NW)

    def pakkunn1_picture_show(self):

        global img1, photo_img1
 
        # キャンバス作成
        canvas1 = tk.Canvas(root, bg="SteelBlue2", height=40, width=35, highlightthickness=0)
        # キャンバス表示
        canvas1.place(x=1296, y=310)
 
        # イメージ作成
        img1 = Image.open("pakkunn.png")
        resized_image1 = img1.resize((38, 40), Image.ANTIALIAS)
        photo_img1 = ImageTk.PhotoImage(resized_image1)
        # キャンバスにイメージを表示
        canvas1.create_image(0, 0, image=photo_img1, anchor=tk.NW)

    


if __name__ == "__main__":
    root = tk.Tk()
    game = Game(root)
    root.mainloop()

自分で試したこと

プログラミング初心者です。
何卒よろしくお願いします。

0

3Answer

playerとphoto_imgをキー入力によって同時に動かしたいです。
今はplayerだけが動いてphoto_imgはそのままです

コードを見ると、関数moveplayerを動かしていますが、photo_imgを乗せたキャンバスを移動させていません。playerと一緒に移動する処理を入れたらどうですか。

0Like

Comments

  1. @iaojfkojgpakm

    Questioner

    回答ありがとうございます!もしよければどのようなプログラムを書けば良いか具体的なコードを教えていただけないでしょうか。お願いいたします!
    self.canvas.move(self.player, dx, dy)のコードの後にself.canvas.move(photo_img, dx, dy)としてできなくて困っています、、

  2. self.canvas.move(self.player, dx, dy)のコードの後にself.canvas.move(photo_img, dx, dy)としてできなくて困っています

    それでは動きませんね。エラーで落ちませんか?
    理由は、photo_imgself.canvasに乗っていないからです。

    self.playerself.canvasに乗っているので動きます。これに倣って、photo_imgを乗せたキャンバスを指定すれば動くようにできるはずです。
    キャンバス.move(対象, dx, dy)

    一度ご自身で考えてみてください。

  3. @iaojfkojgpakm

    Questioner

    返信ありがとうございます!
    self.canvas.move(self.player,dx,dy) self.canvasM.move(photo_img, dx, dy)
    こういうことでしょうか?
    すると’Game’ object has no attribute ‘canvasM’というエラーになってしまいます。。
    何度もすみません!

  4. エラーが示すとおりです。
    self.canvasMに代入する処理が無いのに、それを参照したからエラーになります。
    self.canvasMcanvasMはまったく別物です。

    self.canvasself.playerに代入する処理をよく確認して、それに倣ってください。

  5. @iaojfkojgpakm

    Questioner

    self.canvas.move(self.player,dx,dy) canvasM.move(photo_img, dx, dy)としたら
    name ‘canvasM’ is not definedとなります、、
    self.canvasMに代入する処理とはなんでしょうか、
    よろしくお願いします、、

  6. self.canvasとself.playerに代入する処理をよく確認して、それに倣ってください。

    ちゃんと処理を理解されたのでしょうか???

  7. @iaojfkojgpakm

    Questioner

    self.canvasに乗っているself.playerをx軸にdx 、y軸にdy だけmoveするという認識です

  8. そこではありません。

    コードの↓この処理を理解していますか? と言いました。

    • 10行目辺り
      self.canvas = tk.Canvas(root, width=1500, height=800, bg="SteelBlue2")
      
      self.player = self.canvas.create_rectangle(1470, 305, 1500, 340, fill='blue')
      

    self.canvasMに代入する処理とはなんでしょうか、

    ↑これに対する、回答です。

    そもそもですが、self.の意味を理解されていますか?

  9. @iaojfkojgpakm

    Questioner

    selfはplayerなどの関数をclassの中で引用する時に使うものだと思っています、、

  10. でしたら、この場でのやり取りを最初から読み返すと、

    self.canvasMに代入する処理とはなんでしょうか、

    ↑この疑問は解消されると思いますが、どうでしょうか?

  11. @iaojfkojgpakm

    Questioner

    classの中でself.canvasM= tk.Canvas(root, bg=”streelblue2”, heigh=38, width=35)
    self.canvass.place(x=1466, y=307)
    ということでしょうか、、?

  12. そんな感じです。
    関連してphoto_imgcreate_imageself.xxxに対応する必要があります。

Classの中に
#・キャンバス作成
self.canvasM = tk.Canvas (root,bg="SteelBlue2",height=38, Width=35, highlightthickness=0)
#・キャンパス表示
self.canvasM.place(x=1466, y=312)#(X=1465」y=307)」
self.img = Image.open("mario.png")
self.resized_image = img.resize ((38,48), Image.ANTIALIAS)
self.photo_img = ImageTk. Photoimage(self.resized_image)を追加し

self.canvas.move(self.player,dx,dy)の後にself.canvasM.move(photo_img, dx, dy)を追加しましたが写真は動きません、、
変更点などありますでしょうか、、

0Like

Comments

  1. @iaojfkojgpakm

    Questioner

    解決しました!ありがとうございました!

Your answer might help someone💌