arcade制作的模拟海底世界动画章鱼哥

Octopus demo python街机模块arcade制作的模拟海底动画章鱼哥

以下是部分代码预览:

"""
Octopus demo in sea  by lixingqiu
python街机模块arcade制作的模拟海底动画章鱼哥

"""

__author__ = "lixingqiu"
__date__ = "2014/4/3"
__url__ = "https://www.lixingqiu.com/?p=313"
__qq__ = "406273900"

import os
import arcade
import random

SCREEN_WIDTH = 500
SCREEN_HEIGHT = 685
SCREEN_TITLE = "Octopus demo python街机模块arcade制作的模拟海底动画章鱼哥 "

COIN_SCALE = 1.0
COIN_COUNT = 50

MOVEMENT_SPEED = 5

class Actor(arcade.AnimatedTimeSprite):
    def __init__(self,images,scale):
        super().__init__()
        while images:self.textures.append(arcade.load_texture(images.pop(0),scale= scale))

class Octopus(arcade.Sprite):
    def __init__(self,images):
        super().__init__()
        self.costume_amount = len(images)

        
    def alt_costume(self):
        self.frame_counter += 1
       
            
        
class MyGame(arcade.Window): 

    def __init__(self, width, height, title):
        """ 初始化方法      """
        super().__init__(width, height, title)

        self.background = None
        self.octopus = None
        # 定义所有角色列表                    
        self.all_actor_list = None 
 
    def setup(self):
        self.all_actor_list = arcade.SpriteList() 

        bgimages = ["images/bg2" + os.sep  + f"{index:04d}"  + ".png" for index in range(1,16)]
        self.background = Actor(bgimages,1.0)
        self.background.center_x = SCREEN_WIDTH//2
        self.background.center_y = SCREEN_HEIGHT//2
        self.all_actor_list.append(self.background)

        octopus_images = ["images/octopus/" +  str(i) + ".png" for i in range(1,82)]
        self.octopus = Octopus(octopus_images)
        
        self.octopus.center_x = SCREEN_WIDTH//2
        self.octopus.center_y = SCREEN_HEIGHT//2
        self.octopus.alpha =  80
        self.all_actor_list.append(self.octopus)

    def on_draw(self):
        """   渲染屏幕       """
   
        arcade.start_render() 
        self.all_actor_list.draw()   

    def update(self, delta_time):
        """ 更新角色"""

        self.all_actor_list.update()
        self.all_actor_list.update_animation()
        self.octopus.alt_costume()
 

def main():
    """ 主要方法 """
    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()

下载完整源代码与素材,请扫码付款。

发表在 arcade, python | arcade制作的模拟海底世界动画章鱼哥已关闭评论

pygame图像处理之温度计图片变成gif动态图

以下是部分代码预览:

"""
  pygame图像处理之温度计图片变成gif动态图,本程序把一张png图片变成gif动态图片
  主要原理:通过pygame加载图像,对它进行像素操作,生成一张张的png图片,最后把所有的png图片合成到gif图里。
  
"""
__author__ = "李兴球"
__date__ = "2019/3/30"

import os
import imageio
import pygame

def makegif_image(path_image,gif_filename):
    pass
   
def draw_rect(left,top,width,height):
    pass
 
if __name__ == "__main__":

    source_image = "背景短空-红.png"
    dest_image = "风火轮编程_step.gif"
    images_path= "images"        # 生成的png图片路径
    image_width = 87
    image_height = 532
    start_height = 68
    if not os.path.exists(images_path):os.mkdir(images_path)
    image = pygame.image.load(source_image)
    counter = 0

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | pygame图像处理之温度计图片变成gif动态图已关闭评论

python海龟画图模块实现单击滑动小猫叫动画

"""本程序用海龟画图模块实现单击滑动小猫叫。
刚才用了pygame zero实现一只小猫从左到右不断地滑动,想了想用turtle模块实现一下。

"""

from turtle import *
from winsound import PlaySound,SND_ASYNC

width,height = 480,360
cats_images = ["scratch.gif","scratch1.gif"]
cats_images_index = 0

screen = Screen()
screen.setup(width,height)
screen.bgpic("moon.png")
screen.title("海龟画图点滑动小猫动画_作者:李兴球")
screen.delay(0)
screen.addshape("scratch.gif")
screen.addshape("scratch1.gif")

# 小猫的宽度是184,高度是200
小猫 = Turtle(shape="scratch.gif")
小猫.penup()

def move():
    小猫.setx(小猫.xcor() + 1)
    right = 小猫.xcor() - 92
    if right > width//2 :
        小猫.ht()
        小猫.setx(-width//2-92)
        小猫.st()        
    screen.ontimer(move,10)
move()

def act(x,y):
    global cats_images_index
    print("你用鼠标左键点到我了")
    PlaySound("喵.wav",SND_ASYNC)
    cats_images_index = 1- cats_images_index
    小猫.shape(cats_images[cats_images_index])
    
小猫.onclick(act)
screen.mainloop()
     
    
发表在 python, turtle | python海龟画图模块实现单击滑动小猫叫动画已关闭评论

pygame zero 小猫滑过动画


以下是部分代码预览:

"""pygame zero是给娃娃们学习python游戏入门的一个pygame封装库,
本程序出有一个窗口出现,一只小猫不断地从左到右滑过,单击它会发出喵叫声。
"""

import pgzrun                 # pip install pgzero
 
小猫 = Actor('scratch')       # scratch.png放在images文件夹下      
小猫.pos = 小猫.width//2,小猫.height//2

WIDTH = 小猫.width * 2        # 窗口宽度 
HEIGHT = 小猫.height * 2      # 窗口高度

def update():
    小猫.left += 5
    if 小猫.left > WIDTH:小猫.right=0
      

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame_zero, python | pygame zero 小猫滑过动画已关闭评论

python海龟画图继承与ondrag练习

"""python海龟画图继承与ondrag练习.py
本程序新建Durtle类,生成的拖动角色会换一个造型,松开它会隐藏
能读懂以下代码说明你的python海龟画图上了一个大台阶了。

"""
from turtle import *

class Durtle(Turtle):
    def __init__(self,images):
        Turtle.__init__(self,visible=False)
        self.begin_drag = 0                  # 拖的标志
        self.penup()
        self.images = images                 # 造型列表
        self.index = 0                       # 初始造型索引
        self.amounts = len(images)           # 造型数量

        "设定初始造型"
        self.image = self.images[self.index] # 当前造型
        self.shape(self.image)               # 设定造型
        self.st()                            # 显示
            
        self.ondrag(self.act1)  
        self.onrelease(self.act2)
        
    def alt_costume(self):
        "切换到下一个造型"
        if self.begin_drag == 0:
            self.index = self.index + 1
            self.index = self.index % self.amounts
            self.image = self.images[self.index]
            self.shape(self.image)
        self.begin_drag += 1        
                
    def act1(self,x,y):
        """切换到下一个造型,定位到鼠标指针坐标"""
        self.alt_costume()
        self.goto(x,y)  
        
    def act2(self,x,y):
        self.ht()
        self.goto(10000,10000)         # 走你,扔到远远的一个地方去眼不见为净
        self.begin_drag = 0
        #print("松开")        
          
if __name__ == "__main__":

    images = "dog2-a.gif","dog2-b.gif","dog2-c.gif"

    width,height = 480,360
    screen = Screen()
    screen.setup(width,height)
    screen.delay(0)
    [screen.addshape(image) for image in images]

    d = Durtle(images) 

    screen.mainloop()

 

发表在 turtle | python海龟画图继承与ondrag练习已关闭评论

pymunk教程_自由落体小球_Pymunk滑动和铰接演示教程

使用Pymunk之前的准备工作 

这是Pymunk自带的例子slide_and_pinjointl.py的教程。在阅读这个教程之间需要安装好python3,Pygame(用pip install pygame –user安装和Pymunk。Pygame在这个例子中是必需的,但Pymunk并不能依赖pygame。你可以Pymunk和Pyglet结合重写此教程。

Pymunk使用2D物理库Chipmunk。Chipmunk是用c语言写的。通过Cffi 库能把c语言模块翻译到python语言。如果在某些操作系统上没有Cffi模块,那你必需自己做这个了。不过实际上当你用pip install pymunk安装时,会帮你安装好Cffi 。

在使用pymunk前,在IDLE中导入一下pymunk看它是否正常。如果导入pymunk时发生了错误,可能是没有找到chipmunk 库。如果用pip或setup.py install安装的,应该都会被正确地安装。

一个空的简单模拟

为了学习pymunk,首先要学习几个概念。

刚体

刚体具有物体的物理性质。(质量、坐标、旋转角度、速度等)它本身没有形状。如果你以前做过粒子效果这样的物理实验,刚体的区别主要在于它们能够旋转。

碰撞形状

通过将形状附加到实体,可以定义实体的形状。可以将多个形状附加到单个实体以定义复杂形状,如果不需要形状,则可以不附加任何形状。

约束与关节

你可以在两个实体之间附加关节以约束它们的行为。

空间

空间是Chipmunk的基本模拟单元。你可以将实体、形状和关节添加到空间,然后整体更新空间。

结合pygame的简单物理模拟空示例

import sys
import pygame
from pygame.locals import *
import pymunk #1

def main():
    pygame.init()                                    # pygame初始化                            
    screen = pygame.display.set_mode((600, 600))     # 新建屏幕对象,它是一个surface,应该是最先渲染的面
    pygame.display.set_caption("结合pygame的最简pymunk例子_翻译:李兴球")#显示标题
    clock = pygame.time.Clock()                      # 新建时钟对象  

    space = pymunk.Space() #2
    space.gravity = (0.0, -900.0)                    # 设定重力参数 

    while True:
        for event in pygame.event.get():             # 遍历事件  
            if event.type == QUIT:
                sys.exit(0)
            elif event.type == KEYDOWN and event.key == K_ESCAPE:# 按键检测
                sys.exit(0)

        screen.fill((255,255,255))                   # 填充screen为白色

        space.step(1/50.0) #3

        pygame.display.flip()                        # 刷新整个屏幕  
        clock.tick(50)                               # 设定fps 

if __name__ == '__main__':
    sys.exit(main())

上面的代码只会显示一个空白窗口,一个抽像的啥东西也没有的物理空间。

#1这里是导入pymunk罢了。

#2这里新建物理空间。下面的代码是设定重力加速度啥的。你可以自己选定一个重力参数以适合自己的游戏需求。

#3这是让物理空间的抽象实体在指定的时间步长里前进一步(我的理解是更新坐标方向啥的)。重要的是不要修改这个步长,在恒定的步长下,物理模拟会更好地工作。

自由落体小球

圆形在游戏中容易处理,也容易重画。下面的例子,我们让程序运行的时候不断地产生小球。我们把程序分解成几个函数。首先是下面这个函数:

def add_ball(space):
    mass = 1
    radius = 14
    moment = pymunk.moment_for_circle(mass, 0, radius) # 1
    body = pymunk.Body(mass, moment) # 2
    x = random.randint(120, 380)
    body.position = x, 550 # 3
    shape = pymunk.Circle(body, radius) # 4
    space.add(body, shape) # 5
    return shape

#1、所有物理的惯性必需要设置好。这里是使用pymunk的moment_for_circle函数根据质量和半径计算出来的。你也可以根据经验自己写一个,好用就行了呗。

#2、惯性计算好了就根据质量和moment生成刚体。

#3、这里是设置刚体的坐标。

#4、刚体只是个概念,如果要让它参与碰撞检测,那么要让赋予它形状。(就像人有灵魂,但没有躯壳一样,是无法产生碰撞的)

#5、最后我们把实体,形状添加到物理空间。

现在我们可以创建小球,把它们显示出来。pymunk自带了实用包,有space.debug_draw方法,能把整个空间直接给渲染出来。为了理解原理,我们也可以手工做一下这个工作。debug drawing函数的代码工作原理像下面这样:

def draw_ball(screen, ball):
    p = int(ball.body.position.x), 600-int(ball.body.position.y)
    pygame.draw.circle(screen, (0,0,255), p, int(ball.radius), 2)

在循环里,我们要一个一个来渲染它们。假设有一个球列表叫balls,space.debug_draw方法还要一个一个把它们画出来,代码像下在这样:

for ball in balls:
    draw_ball(screen, ball)

在这个例子中,我们就简单化,不自己写上面的代码了,用Pymunk自带的函数完成上面的任务。首先用下面的命令创建draw_options。

draw_options = pymunk.pygame_util.DrawOptions(screen)

然后在pygame的游戏循环中一下子重画所有形状,用以下命令:

space.debug_draw(draw_options)

大多数的pymunk作品都是用自带的实用函数完成以上任务。下面是自由落体小球代码:

import sys, random
import pygame
from pygame.locals import *
import pymunk

def add_ball(space):
    mass = 1
    radius = 14
    moment = pymunk.moment_for_circle(mass, 0, radius) # 1
    body = pymunk.Body(mass, moment) # 2
    x = random.randint(120, 380)
    body.position = x, 550 # 3
    shape = pymunk.Circle(body, radius) # 4
    space.add(body, shape)

def main():
    pygame.init()
    screen = pygame.display.set_mode((600, 600))
    pygame.display.set_caption("Joints. Just wait and the L will tip over")
    clock = pygame.time.Clock()

    space = pymunk.Space()
    space.gravity = (0.0, -900.0)

    balls = []
    draw_options = pymunk.pygame_util.DrawOptions(screen)


    ticks_to_next_ball = 10
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit(0)
            elif event.type == KEYDOWN and event.key == K_ESCAPE:
                sys.exit(0)

        ticks_to_next_ball -= 1
        if ticks_to_next_ball <= 0:
            ticks_to_next_ball = 25
            ball_shape = add_ball(space)
            balls.append(ball_shape)

        space.step(1/50.0)

        screen.fill((255,255,255))
        space.debug_draw(draw_options)

        pygame.display.flip()
        clock.tick(50)

if __name__ == '__main__':
    main()

L形静止拦板

单单几个小球自由落体,很多人不用物理引擎也能完成。这体现不出pymunk的强大。下面我们创建一个L形的拦板,让小球掉在上面。 我们通过创建一个函数来完成这个任务,以下是代码:

def add_static_L(space):
    body = pymunk.Body(body_type = pymunk.Body.STATIC) # 1
    body.position = (300, 300)
    l1 = pymunk.Segment(body, (-150, 0), (255, 0), 5) # 2
    l2 = pymunk.Segment(body, (-150, 0), (-150, 50), 5)

    space.add(l1, l2) # 3
    return l1,l2

#1、这里创建的是静止的实体,重要的是不要把它加到space中。注意这个body类型是pymunk.Body.STATIC。

#2、添加线条,坐标相对于body

#3、把l1和l2添加到空间。

在这个例子中使用的是Space.debug_draw来渲染整个空间。所以我们不需要给以上用Segment创建的线条手工写代码,为了了解原理,下面代码演示了渲染线条的功能:

def draw_lines(screen, lines):
    for line in lines:
        body = line.body
        pv1 = body.position + line.a.rotated(body.angle) # 1
        pv2 = body.position + line.b.rotated(body.angle)
        p1 = to_pygame(pv1) # 2
        p2 = to_pygame(pv2)
        pygame.draw.lines(screen, THECOLORS["lightgray"], False, [p1,p2])

#1、我们做了个计算,这是为了得到旋转后线条两端的点的坐标。line.a是线条的第一个点,line.b是线条的第二个点。虽然现在线条是静止的,但是接下来会让它旋转,所以要做这个计算。line.a.rotated(body.angle)是向量旋转,结果加上body.position,那么点a就是新的坐标了。 如果对向量旋转不太明白,可以复习一下相关知识。

#2、由于pygame和pymunk的坐标系不同。下面的to_pygame函数把坐标转换成pygame坐标系的坐标点。

def to_pygame(p):
    """Small hack to convert pymunk to pygame coordinates"""
    return int(p.x), int(-p.y+600)

现在,我们能看到不断掉落的小球,碰到L形拦板的效果了,下面是代码:

import sys, random
import pygame
from pygame.locals import *
import pymunk
import math

#def to_pygame(p):
#def add_ball(space):
#def add_static_l(space):

def main():
    pygame.init()
    screen = pygame.display.set_mode((600, 600))
    pygame.display.set_caption("Joints. Just wait and the L will tip over")
    clock = pygame.time.Clock()

    space = pymunk.Space()
    space.gravity = (0.0, -900.0)

    lines = add_static_L(space)
    balls = []
    draw_options = pymunk.pygame_util.DrawOptions(screen)

    ticks_to_next_ball = 10
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit(0)
            elif event.type == KEYDOWN and event.key == K_ESCAPE:
                sys.exit(0)

        ticks_to_next_ball -= 1
        if ticks_to_next_ball <= 0:
            ticks_to_next_ball = 25
            ball_shape = add_ball(space)
            balls.append(ball_shape)

        space.step(1/50.0)

        screen.fill((255,255,255))
        space.debug_draw(draw_options)

        pygame.display.flip()
        clock.tick(50)

if __name__ == '__main__':
    (main()

关节(1)

用静止的L形拦板来拦小球也是没有啥好玩的。接下来增加两个关节,一个用来让body旋转,另一个关节则限制它旋转。下面的代码只是增加了让它旋转的代码。由于L形拦板不再是静止的,所以给函数改名为add_L,代码如下所示:

def add_L(space):
    rotation_center_body = pymunk.Body(body_type = pymunk.Body.STATIC) # 1
    rotation_center_body.position = (300, 300)

    body = pymunk.Body(10, 10000) # 2
    body.position = (300, 300)
    l1 = pymunk.Segment(body, (-150, 0), (255.0, 0.0), 5.0)
    l2 = pymunk.Segment(body, (-150.0, 0), (-150.0, 50.0), 5.0)

    rotation_center_joint = pymunk.PinJoint(body, rotation_center_body, (0,0), (0,0)) # 3

    space.add(l1, l2, body, rotation_center_joint)
    return l1,l2

#1、这是旋转中心body。它是静上的,目的是做为关节让线条body旋转,不会被加到space中。

#2、L形拦板不再是静止的了,所以这里的代码改了。我把它的惯性设为10000,这个值并不是计算出来的(自己随便写的),反正能有用就行了。

#3、新建销关节,充许两个物体绕着关节旋转。(相当在body中插入一根销,这样body就能转起来,lixingqiu加的)。在这个例子中有一个物体会粘在世界中。

关节(2)

前面我们增加了一个销关节,是时候创建限制它的行为,让仿真程序更有趣了。以下是修改后的add_L函数:

def add_L(space):
    rotation_center_body = pymunk.Body(body_type = pymunk.Body.STATIC)
    rotation_center_body.position = (300,300)

    rotation_limit_body = pymunk.Body(body_type = pymunk.Body.STATIC) # 1
    rotation_limit_body.position = (200,300)

    body = pymunk.Body(10, 10000)
    body.position = (300,300)
    l1 = pymunk.Segment(body, (-150, 0), (255.0, 0.0), 5.0)
    l2 = pymunk.Segment(body, (-150.0, 0), (-150.0, 50.0), 5.0)

    rotation_center_joint = pymunk.PinJoint(body, rotation_center_body, (0,0), (0,0))
    joint_limit = 25
    rotation_limit_joint = pymunk.SlideJoint(body, rotation_limit_body, (-100,0), (0,0), 0, joint_limit) # 2

    space.add(l1, l2, body, rotation_center_joint, rotation_limit_joint)
    return l1,l2

#1、增加一个实体。

#2、创建一个滑动关节,它有销关节有点像。它的作用是让两个body在一定的距离之间滑动。在这里让有一个body 静止,就是rotation_limit_body。所以另一个body就会在一定范围内被限制。

结尾

或许你注意到在程序中没有删除球的设计。这会让球越来越多,导致仿真程序运行越来越慢。所以还要加上当小球超出屏幕范围把它删除的代码,以下就是:

balls_to_remove = []
for ball in balls:
    if ball.body.position.y < 0: # 1
        balls_to_remove.append(ball) # 2

for ball in balls_to_remove:
    space.remove(ball, ball.body) # 3
    balls.remove(ball) # 4

#1、遍历每个小球检测它的坐标是否小于0,这里的ball.body.position并不是pygame坐标系。

#2、如果小球的y坐标小于0,加到待删除列表。

#3、从重力空间中移去小球和它的形状。

#4、从自建的球们列表中移去这个小球。

现在,教程已经完成了。你运行程序能看到不断掉落的小球,它们碰到倒L形拦板,可能会呆在里面,当满的的时候会溢出来。 以下是这个仿真程序的所有代码:

import sys, random
import pygame
from pygame.locals import *
import pymunk
import pymunk.pygame_util

def add_ball(space):
    """Add a ball to the given space at a random position"""
    mass = 1
    radius = 14
    inertia = pymunk.moment_for_circle(mass, 0, radius, (0,0))
    body = pymunk.Body(mass, inertia)
    x = random.randint(120,380)
    body.position = x, 550
    shape = pymunk.Circle(body, radius, (0,0))
    space.add(body, shape)
    return shape

def add_L(space):
    """Add a inverted L shape with two joints"""
    rotation_center_body = pymunk.Body(body_type = pymunk.Body.STATIC)
    rotation_center_body.position = (300,300)

    rotation_limit_body = pymunk.Body(body_type = pymunk.Body.STATIC)
    rotation_limit_body.position = (200,300)

    body = pymunk.Body(10, 10000)
    body.position = (300,300)
    l1 = pymunk.Segment(body, (-150, 0), (255.0, 0.0), 5.0)
    l2 = pymunk.Segment(body, (-150.0, 0), (-150.0, 50.0), 5.0)

    rotation_center_joint = pymunk.PinJoint(body, rotation_center_body, (0,0), (0,0))
    joint_limit = 25
    rotation_limit_joint = pymunk.SlideJoint(body, rotation_limit_body, (-100,0), (0,0), 0, joint_limit)

    space.add(l1, l2, body, rotation_center_joint, rotation_limit_joint)
    return l1,l2

def main():
    pygame.init()
    screen = pygame.display.set_mode((600, 600))
    pygame.display.set_caption("销关节滑动关节小球掉落倒L形拦板仿真程序_www.lixingqiu.com")
    clock = pygame.time.Clock()

    space = pymunk.Space()
    space.gravity = (0.0, -900.0)

    lines = add_L(space)
    balls = []
    draw_options = pymunk.pygame_util.DrawOptions(screen)

    ticks_to_next_ball = 10
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit(0)
            elif event.type == KEYDOWN and event.key == K_ESCAPE:
                sys.exit(0)

        ticks_to_next_ball -= 1
        if ticks_to_next_ball <= 0:
            ticks_to_next_ball = 25
            ball_shape = add_ball(space)
            balls.append(ball_shape)

        screen.fill((255,255,255))

        balls_to_remove = []
        for ball in balls:
            if ball.body.position.y < 150:
                balls_to_remove.append(ball)

        for ball in balls_to_remove:
            space.remove(ball, ball.body)
            balls.remove(ball)

        space.debug_draw(draw_options)

        space.step(1/50.0)

        pygame.display.flip()
        clock.tick(50)

if __name__ == '__main__':
    main()

 

 

 

发表在 pymunk, python | pymunk教程_自由落体小球_Pymunk滑动和铰接演示教程已关闭评论

pymunk物理引擎说明

Pymunk(派曼k)是一个容易使用的Python二维物理引擎,当你要使用Python进行2D刚体物理编程演示与开发应用程序时,它是最好的选择。它基于著名的Chipmunk库。
第一个版本诞生自2007年,一直到维护到今天。
Pymunk已经有玩家用它开发了很多好玩的项目。例如在python周赛上产生了3个获奖者,还有许多科学论文使用了它。有人用它做了辆自驾车模拟。更多Pymunk请查看本站相关网页。

下面的版本是5.4.2版,使用的核心是Chipmunk7.0。安装方法是在命令提示符中输入:pip install pymunk。

下面是一个快速的例子:

 

import pymunk               # 导入pymunk模块

space = pymunk.Space()      # 创建物理空间
space.gravity = 0,-1000     # 设置重力加速度

body = pymunk.Body(1,1666)  # 创建有一个有质量和惯性的刚体
body.position = 50,100      # 设置刚体的坐标

poly = pymunk.Poly.create_box(body) # 创建一个盒子形状,它附在刚体上。(但仍是不可见的)
space.add(body, poly)       # 增加刚体和形状到重力空间

while True:                 # 无限循环
    space.step(0.02)        # 推进模拟,数值越小越精确

用pip命令并没有安装示例,可以从这个网址下载源代码,还有说明文档。

链接:https://pan.baidu.com/s/1pSFKK72GVDZg5nR_PpcTdA
提取码:ywvt

这个引擎可以和pygame或pyglet甚至海龟画图模块等结合起来使用。 关注本博客,获取更多案例。

python2D游戏物理引擎pymunk

python2D游戏物理引擎pymunk

发表在 pymunk, python | pymunk物理引擎说明已关闭评论

arcade结合物理引擎pymunk金币弹弹弹_作者:李兴球


以下是部分代码预览:

"""
arcade结合物理引擎pymunk金币弹弹弹_作者:李兴球
本程序用arcade模块结合pymunk模块制作很多金币下落效果,它们之间互相有碰撞。
pymunk手册:http://www.pymunk.org/en/latest/pymunk.html

"""
import random
import arcade
import pymunk
import timeit
import math
import os

SCREEN_WIDTH = 1200
SCREEN_HEIGHT = 800


class MyGame(arcade.Window):
    """继承自窗口的游戏类 """

    def __init__(self, width, height):
        super().__init__(width, height,'arcade结合物理引擎pymunk金币弹弹弹_作者:李兴球') 

        arcade.set_background_color(arcade.color.DARK_SLATE_GRAY)

        self.frames_counter = 0             # 帧计数器

        #  Pymunk 重力空间
        self.space = pymunk.Space()         # 游戏的重力空间
        self.space.gravity = (0.0, -180.0)  # 设置游戏重力空间的重力参数
   

    def spawn(self):
        
        """产生一枚金币金币"""
        size = 45
        mass = 1
        radius = 10
        inertia = pymunk.moment_for_circle(mass, 0, radius, (0, 0))       # 惯性
        body = pymunk.Body(mass, inertia)
        body.position = pymunk.Vec2d(SCREEN_WIDTH//2,SCREEN_HEIGHT//2)
 
        self.sprite_list.append(sprite)


    def on_draw(self):
        """        渲染屏幕.        """        
        arcade.start_render()

        # 记录此帧开始渲染时间
        draw_start_time = timeit.default_timer()

        # 画所有的角色
        self.sprite_list.draw()

        # 画地板
        for line in self.static_lines:
            body = line.body
            pv1 = body.position + line.a.rotated(body.angle)
            pv2 = body.position + line.b.rotated(body.angle)
            arcade.draw_line(pv1.x, pv1.y, pv2.x, pv2.y, arcade.color.WHITE, 2)

        # 显示时间
        output = f"处理时间: {self.processing_time:.3f}"
        arcade.draw_text(output, 20, SCREEN_HEIGHT - 20, arcade.color.WHITE, 12,font_name='simkai')

        output = f"渲染时间: {self.draw_time:.3f}"
        arcade.draw_text(output, 20, SCREEN_HEIGHT - 40, arcade.color.WHITE, 12,font_name='simkai')

        self.draw_time = timeit.default_timer() - draw_start_time # 渲染此帧所用时间
 

    def update(self, delta_time):
        start_time = timeit.default_timer()
        self.frames_counter +=1
        if self.frames_counter % 20 == 0 :        self.spawn()



def main():
    MyGame(SCREEN_WIDTH, SCREEN_HEIGHT)

    arcade.run()


if __name__ == "__main__":
    main()

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, pymunk, python | arcade结合物理引擎pymunk金币弹弹弹_作者:李兴球已关闭评论

python海龟画图的物理互碰弹球


以下是部分代码预览:

"""让海龟画图插上物理引擎的翅膀,丑小鸭变白天鹅了。
本程序新建物理弹球类,它继承自海龟类。给它新增了一些描述物理性质的属性,
这些物理性质来自pymunk。
"""
import pymunk                       # 导入pymunk模块
import turtle                       # 导入海龟模块,用它来渲染刚体
import random

class PhysicBall(turtle.Turtle):
    def __init__(self,space,image,position):
        turtle.Turtle.__init__(self,visible=False)
        self.raw_position = position
        self.space = space          # 弹球的重力空间
        self.penup()
        self.shape(image)           # 设定形状
        self.mass = 1               # 质量为1

        
    def reborn(self):
        self.body.velocity= (0,0) 
        direction =  random.randint(-3000,3000),random.randint(6000,7000)
        self.body.force = direction                      # 给力
        self.body.position = self.raw_position[0],self.raw_position[1]
        self.goto(self.raw_position)
        self.st()
        
            
width,height = 600,600
balls_list = []

screen = turtle.Screen()                 # 新建海龟窗口,用于渲染形状的
screen.delay(0)
screen.title("python海龟画图的物理互碰弹球_作者:李兴球")
screen.setup(600,600)
screen.bgcolor("cyan")
screen.addshape("绿球.gif")

space = pymunk.Space()                   # 设定重力空间
space.gravity = 0,-200                   # 设置重力参数

# platform是平台,它只是真正的平台的外表
platform = turtle.Turtle(shape='square')  # 这是画棕色的棒子,它只是用来显示下面的staticbody的
platform.color("brown")
platform.penup()
platform.shapesize(1,15)
platform.setposition(0,-200)

 

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pymunk, python, turtle | python海龟画图的物理互碰弹球已关闭评论

学习Python本领高_Python制作的街机

由于gif截屏软件对图片进行了压缩,所以gif图不怎么漂亮哟。
以下是部分代码预览:

"""
学习Python本领高.py,本程序操作一个小人上下午左右移动收集Python本领。
"""
import os
import time
import arcade
import random


TOTAL_TIME = 100            # 100秒时间
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "学习Python本领高"

COIN_SCALE = 0.5
COIN_COUNT = 2

MOVEMENT_SPEED = 2         # 移动速度常量

SKILLS = ['自动写作业','游戏开发','网站编程','数据库开发','指挥机器人']
SKILLS.extend(['人脸识别','自动下载','自动点赞','识别假粉丝','自动登陆'])
SKILLS.extend(['自动发帖子','自动买零食','自动点赞','识别假粉丝','自动登陆'])
SKILLS.extend(['数据处理','图形处理','自动控制','科学计算','成批处理文件'])
SKILLS.extend(['自动打怪','软件开发','手机APP制作','大型网站开发','制作搜索引擎'])
SKILLS.extend(['语音识别','自动加密','破解密码','数据采集','远程控制'])
SKILLS.extend(['趣味绘画','无人机控制','数据可视化','远程监控','系统运维'])
SKILLS.extend(['远程登陆','硬件开发','大数据统计','人工智能','教别人编程'])
SKILLS.extend(['音乐谱曲','网络安全','大数据统计','人工智能','教别人编程'])

class Explosion(arcade.Sprite):
    """ 创建可爆炸的角色 """ 

    def __init__(self, texture_list,x,y):
        """texture_list是已经load了的造型列表"""
        super().__init__()

        self.center_x = x
        self.center_y = y
        # 第一帧
        self.current_texture = 0      # 这是造型索引号
        self.textures = texture_list  # 这是每帧图片列表
        self.set_texture(self.current_texture)

    def update(self):

        # 更新每帧的图片,到了最后一帧后就会删除自己。
        self.current_texture += 1
        if self.current_texture < len(self.textures):
            self.set_texture(self.current_texture)
        else:
            self.kill()

class Effect(arcade.Sprite):
    def __init__(self,x,y,sc):
        super().__init__("images/lovely_turtle.png",scale=sc)
        self.alpha = 50
        self.center_x = x
        self.center_y = y
        self.change_y = 2
        
    def update(self):
        super().update()
        if self.bottom > SCREEN_HEIGHT :self.kill()        
    
    
class Coin(arcade.AnimatedTimeSprite):
    def __init__(self):
        super().__init__(scale=0.5)
        
        self.center_x = random.randrange(SCREEN_WIDTH)
        self.center_y = random.randrange(SCREEN_HEIGHT,SCREEN_HEIGHT*2)
        self.change_y = -1                      # 会往下掉
        self.textures = []
        self.textures.append(arcade.load_texture("images/gold_1.png", scale=COIN_SCALE))
        self.textures.append(arcade.load_texture("images/gold_2.png", scale=COIN_SCALE))
        self.textures.append(arcade.load_texture("images/gold_3.png", scale=COIN_SCALE))
        self.textures.append(arcade.load_texture("images/gold_4.png", scale=COIN_SCALE))
        self.textures.append(arcade.load_texture("images/gold_3.png", scale=COIN_SCALE))
        self.textures.append(arcade.load_texture("images/gold_2.png", scale=COIN_SCALE))
        self.cur_texture_index = random.randrange(len(self.textures))

        self.string =   random.choice(SKILLS)  # 金币顶上的字

    def update(self):
        super().update()
        if self.top < 0 :self.kill()        

class MyGame(arcade.Window):
    """ 继承自窗口的Window类. """

    def __init__(self, width, height, title):
        """
        初始化方法
        """
        super().__init__(width, height, title)
        self.frame_counter = 0                    # 帧计数器
        self.counter_down = TOTAL_TIME
        self.coin_sound =  arcade.sound.load_sound("images/recording1.wav")# 金币声
        self.bang_sound = arcade.sound.load_sound("images/explosion.wav")  # 爆炸声
        self.begin_time = time.time()
        self.game_over = False
 
    def setup(self):        
        
        self.explosion_images = []


        self.player.texture_change_distance = 20

        self.player.center_x = SCREEN_WIDTH // 2
        self.player.center_y = SCREEN_HEIGHT // 2 -100
        self.player.scale = 0.5
        self.player.lives = 3            # 还剩下的生命个数
        self.player.status = True        # 生命状态        
        self.player.reborn_time = 160    # 初始复活时间 

        for i in range(COIN_COUNT):
            coin = Coin()                
            self.coin_list.append(coin)
            self.all_sprites_list.append(coin)
            
        # 设置背景颜色
        arcade.set_background_color(arcade.color.AMAZON)

    def on_draw(self):
        """
        渲染屏幕
        """

        # 开始渲染屏幕
        arcade.start_render()

        self.background.draw()
        # 画所有的角色
        self.all_sprites_list.draw()

        beyond_border = self.player.left < 0 or self.player.right > SCREEN_WIDTH
        beyond_border = beyond_border or self.player.top < 0 or self.player.bottom > SCREEN_HEIGHT
        if not beyond_border:self.player.draw()
        
        for coin in self.coin_list:             
            x = coin.center_x -35
            y = coin.center_y + 25            
            arcade.draw_text(coin.string, x, y, arcade.color.WHITE, 14,font_name='simhei')            

        # 画文本在屏幕上
        output = f"当前得分: {int(self.score) }"
        arcade.draw_text(output, SCREEN_WIDTH//2-100, SCREEN_HEIGHT-100, arcade.color.CYAN, 24,font_name='simkai')

        # 画倒计时在屏幕上         
        arcade.draw_text(str(int(self.counter_down)), SCREEN_WIDTH//2, SCREEN_HEIGHT-50, arcade.color.WHITE, 14 )

        # 画游戏结束的字在屏幕上
        if self.game_over :                            
            arcade.draw_text(" 游 戏 结 束 ", SCREEN_WIDTH//2-150, SCREEN_HEIGHT//2, arcade.color.WHITE, 44 ,font_name='simkai')
            

    def on_key_release(self, key, modifiers):
        """
        当松开按键时会调用这个函数
        """
        
        if self.game_over : return
        
        if key == arcade.key.UP or key == arcade.key.DOWN:
            self.player.change_y = 0
        elif key == arcade.key.LEFT or key == arcade.key.RIGHT:
            self.player.change_x = 0

    def update(self, delta_time):
        """ 移动与更新游戏的代码在这里编写 """

        if random.randint(1,200) == 1 and not self.game_over : 
            bomb = arcade.Sprite("images/bomb.png")
            bomb.alpha = 50
            self.bomb_list.append(bomb)
            self.all_sprites_list.append(bomb)
            bomb.center_x = random.randrange(SCREEN_WIDTH)
            bomb.center_y = random.randrange(SCREEN_HEIGHT)
            if arcade.get_distance_between_sprites(bomb,self.player)< 100 : bomb.kill()           
            
       


def main():
    """ 主要函数"""
    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
     
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, python | 学习Python本领高_Python制作的街机已关闭评论

python用fpdf模块将多张图片合并为PDF,亲测可用

"""将多张图片合并为PDF,亲测可用"""
import os
from fpdf import FPDF

path = "e:\\Python\教程\\哪吒系列\\Python_L3_进阶篇"

pdf = FPDF()
imagelist  = []
for image in os.listdir(path):
        if ".png" in image:
            filename = path + os.sep + image
            imagelist.append(filename)
            
for image in imagelist:
    pdf.add_page()
    pdf.image(image)
pdf.output("e:/哪咤学编程之进阶篇.pdf", "F")

 
print(help(pdf.image))

 

发表在 python | python用fpdf模块将多张图片合并为PDF,亲测可用已关闭评论

Python物理沙盒粒子效果

仔细看这个粒子效果,粒子之间也有碰撞。

以下是部分代码预览:

"""用物理沙盒制作的粒子效果"""

from pyphysicssandbox import *
from random import randint
    
    
class Particle:
    def __init__(self):        
        self.ball = ball((200+randint(-1,1), 350+randint(-1,1)), 2)
        self.direction = randint(-500,500),randint(-3000,-2000)

        
class ColoredParticle(Particle):
    def __init__(self,c):
        super().__init__()       
        self.color = c 
        self.ball.color = self.color
        
window("Python物理沙盒粒子效果", 400, 400)

如需要查看完整代码,请:

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 physicssandbox, python | Python物理沙盒粒子效果已关闭评论

pillow的draw功能在图像指定的位置上写字符串

以下是部分代码预览:

"""本函数调用pillow的draw功能在图像指定的位置上写字符串,这是核心代码,需要定制功能请自行修改程序"""

from PIL import Image,ImageFont, ImageDraw

def print_string_on_image(inimagefile,string,outfile):
    """在图像的底部居中位置印上字符串"""

infile = "跳台背景.jpg"
string = "本书授权给尊敬的张三丰阅读"
outfile = "跳台背景2.jpg"

print_string_on_image(infile,string,outfile)

 

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pillow, python | pillow的draw功能在图像指定的位置上写字符串已关闭评论

和Arcade街机模块作者的交流email_爆炸造型数量有限制!

用Python编了个街机游戏,在公司的电脑运行得好好的。回到家里运行却出错了?调试了一会儿,看了看paul Vincent Craven的原版例子,竟然也是出错了。难道是电脑问题?想到我的电脑很久没有重启了,于是就重启了一下。问题依旧,仔细看了一下,在红色的一在片异常提示中有一个字符串: raise GLException(f”Unable to create texture. {GL_MAX_TEXTURE_SIZE} {size}”)。GL应该是大于的意思,那么这个说的应该是超过了最大的纹理造型尺寸。我想可能是电脑性能限制,低性能的电脑不支持更多的角色造型。于是更改爆炸角色的造型数量,结果我和设想的一样。不过还是给作者发了封电邮,这回第二天就回了。下面是他的回答:

Interesting. Max texture size is determined by your graphics card. Looks like yours does not go as high.

Look at line 27 on that example for:
EXPLOSION_TEXTURE_COUNT = 60
Make the number smaller until it works.
There are things that can be done to support more textures, which need to be coded.

Paul Vincent Craven
结果和我设想的大致差不多,不过知道了是显卡的限制,并且知道了可以通过编程突破这个限制。
发表在 arcade | 和Arcade街机模块作者的交流email_爆炸造型数量有限制!已关闭评论

和Arcade街机模块作者的交流email_how to change sprite’s scale dynamicly?

Try changing width and height. I think those should work. Need to code scale to work.

Paul Vincent Craven

 

On Mon, Mar 18, 2019 at 9:10 PM 李兴球 <406273900@qq.com> wrote:

hello, I want to change sprite’s scale , when its moving, below is a example code  :

 
class Effect(arcade.Sprite):
    def __init__(self,x,y):
        super().__init__(“images/lovely_turtle.png”,scale=0.1)
        self.alpha = 50
        self.center_x = x
        self.center_y = y
        self.change_y = 1
        
    def update(self):
        super().update()
        if self.bottom > SCREEN_HEIGHT :self.kill()
        self.scale += 0.1 
 
But it is not change scale when it moving. How can change it size when it moving?

我问的是:如何在角色移动的时候动态的改变角色的大。

Paul Vincent Craven回答说:改变角色的宽度或高度应该有用,需要编码才能工作。

发表在 arcade | 和Arcade街机模块作者的交流email_how to change sprite’s scale dynamicly?已关闭评论

pygame风火轮少儿编程正弦字画生成gif

这是用pygame进行图像处理的例子。通过合成图层,pygame可以进行丰富的像素级别的图像处理功能。

"""pygame图像处理之生成风火轮少儿编程正弦gif图.
这个程序生成字图层合成到screen后输出为png文件,最后把所有的png文件又合成一个gif动态文件。
学习了本程序的原理后,就能制作好多gif动画了,比如让字跳动起来,做下雨效果动画gif。"""

__author__ = "李兴球"
__date__ = "2019/3/18"

import pygame,time
from pygame import *
import math,os       # 由于pygame有math,所以要在最后导入math模块
import imageio

def makegif(path,filename):
   """把png文件合成gif文件"""
   images = []
   amount = len(os.listdir(path))   
   for i in range(1,amount+1):
       file = path + os.sep + str(i) + ".png"
       images.append(file)  
   frames = [imageio.imread(image) for image in images]
   imageio.mimsave(filename, frames, 'GIF', duration=0.5) 

path = "C:/" + os.sep + "save"
if not os.path.exists(path):os.mkdir(path)
string = "风火轮少儿编程"
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 360
CENTER_X = SCREEN_WIDTH//2
CENTER_Y = SCREEN_HEIGHT//2
size = (SCREEN_WIDTH,SCREEN_HEIGHT)

pygame.init()
screen = pygame.display.set_mode(size)
pygame.display.set_caption("pygame风火轮少儿编程正弦字画生成gif示例_作者:李兴球")
screen.fill((255,255,255))
msyhfont = pygame.font.Font('msyh.ttf',24)  # 新建微软雅黑字体

i = 0
counter = 0
for angle in range(-180,181,26):    
    x = CENTER_X + angle
    y = CENTER_Y + 70 * math.sin(math.radians(angle))
    y = int(y)
    char = string[i]    # 取一个汉字
    i = i + 1
    i = i % len(string)
    counter = counter + 1 # 下面这句是合成图像层
    txt_image = msyhfont.render(char,True,(255,0,255))
    txt_rect = txt_image.get_rect()
    txt_rect.center = x,y
    screen.blit(txt_image,txt_rect)
    filename = path + os.sep + str(counter) + ".png"
     
    pygame.image.save(screen,filename)   # 保存到png文件
    pygame.display.update()
pygame.quit()
makegif(path,string + ".gif") 

发表在 pygame | pygame风火轮少儿编程正弦字画生成gif已关闭评论

简易画梯子程序

"""少儿python编程_简易画梯子程序.py
这是一个简单的画台阶的例子。

"""

from turtle import *

screen = Screen()
screen.setup(486,368)
screen.title("简易画梯子程序")

t = Turtle()
t.penup()
t.pensize(2)
t.color("blue")
t.goto(-240,-175)

t.pendown()
for i in range(23):
    t.setx(t.xcor() + 20) # x坐标增加20
    t.sety(t.ycor() + 15) # y坐标增加15
t.setx(t.xcor() + 20)

t.penup()
t.goto(-235,-190)

# 下面是画梯子下面的数字
for i in range(1,24):
    t.setx(t.xcor() + 20)
    t.sety(t.ycor() + 15)
    t.write(i)
t.setx(t.xcor() + 20)

发表在 turtle | 简易画梯子程序已关闭评论

正弦弯字组成的风火轮少儿编程

"""正弦弯字组成的风火轮少儿编程.py,本程序结合了三角正弦函数,可以用来教授初中生学习python。"""

__author__ = "lixingqiu"

import math
from turtle import Turtle

t = Turtle(visible=False)
t.screen.title("正弦弯字组成的风火轮少儿编程")
f = ("黑体",20,"normal")
t.penup()
s = "风火轮少儿编程"
t.bk(180)
i = 0
# angle是自变量,y就是因变量
for angle in range(-180,181,26):
    y = 70 * math.sin(math.radians(angle))
    y = int(y)
    char = s[i]    # 取一个汉字
    i = i + 1
    i = i % 7
    t.goto(angle,y)# 定位
    t.write(char,font=f)
t.screen.exitonclick()
    

    

 

发表在 turtle | 正弦弯字组成的风火轮少儿编程已关闭评论

python演示马达发动齿轮把粒子们甩开的例子

以下是部分代码预览:

"""
演示马达发动齿轮把盒子们甩开的例子
"""

from pyphysicssandbox import *
import random

width = 300      # 窗口的宽度
height = 300     # 窗口的高度
how_many = 5000  # 粒子的数量

window('演示马达发动齿轮把粒子们甩开的例子', width, height)

arm1 = box((100, 235), 100, 10, 100)
arm1.color = Color("yellow")

pivot1 = pivot((150, 240)) # 新建支点
pivot1.connect(arm1)       # 支点连接到臂
 

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 physicssandbox, python | python演示马达发动齿轮把粒子们甩开的例子已关闭评论

python简单物理引擎受重力的文字效果

以下是部分代码预览:

"""
python简单物理引擎受重力的文字效果
"""

from pyphysicssandbox import *

window('风火轮少儿编程', 500, 600)
Color("red")

# 新建一个不动的地板
floor = static_box((0, 500), 500, 10) # 坐标,宽度,高度
floor.color = Color('blue')
"""


如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 physicssandbox, python | python简单物理引擎受重力的文字效果已关闭评论

python物理沙盒齿轮演示

以下是部分代码预览:

"""
演示齿轮的一个例子,按b键会生成小球,小球掉落会让齿轮旋转。
"""

from pyphysicssandbox import *

def my_observer(keys):
    if constants.K_b in keys:
        ball1 = ball((125, 50), 10, 100)
        ball1.color = Color('green')

window('python物理沙盒齿轮演示', 300, 300)

arm1 = box((100, 90), 100, 10, 100) # 新建矩形
arm1.color = Color("yellow")

pivot1 = pivot((150, 95))   # 新建枢轴
pivot1.connect(arm1)        # 枢轴连接到矩形

arm2 = box((100, 200), 100, 10, 100)
arm2.color = Color("blue")

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 physicssandbox, python | python物理沙盒齿轮演示已关闭评论

Python物理沙盒画房子

以下是部分代码预览:

"""
简单的例子演示如何用物理沙盒画房子

"""
from pyphysicssandbox import *
import random

window("Python物理沙盒画房子", 400, 400)

color('red')                  # 设定颜色为红色
box((100, 200), 200, 200)     # 画矩形
color('white')                # 设定颜色为白色

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 physicssandbox, python | Python物理沙盒画房子已关闭评论

Python物理沙盒碰撞处理演示

以下是部分代码预览:

"""
碰撞处理演示,本程序演示了当小球和地板碰到的时候如何使用函数来处理它们。
pyphysicssandbox是pygame和pymunk的封装,它的设计是用来教授少儿python编程入门。

"""

from pyphysicssandbox import *
import random

def ball_hits_floor(ball1, floor, p):
    """当小球碰到地板时调用这个函数,它让小球的颜色改变"""
    r,g,b = random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
    ball1.color = Color(r,g,b)
 
    return True

window('Python物理沙盒碰撞处理演示', 300, 300)
print(dir(window))
count = 0

 

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 physicssandbox, python | Python物理沙盒碰撞处理演示已关闭评论

Python物理引擎的杠杆演示

以下是部分代码预览:


from pyphysicssandbox import *

WIN_WIDTH = 500
WIN_HT = 600
window("Python物理引擎的杠杆演示", WIN_WIDTH, WIN_HT)
gravity(0.0, 10.0)

# 黑色的地板
base = static_box((0, 500), WIN_WIDTH, 10)
base.color = Color("black")

# 绿色的三角形支掌点
triangle = polygon(((250, 450), (275, 500), (225, 500)))
triangle.color = Color("green")

# 深蓝色的杠杆
lever = polygon(((50, 390), (65, 390), (65, 430), (450, 430), (450, 450), (50, 450)))
lever.color = Color("darkblue")
lever.elasticity = 0.90

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 physicssandbox, python | Python物理引擎的杠杆演示已关闭评论

pymunk物理引擎之掉落的弹球

""" 这是一个动画,它不断地产生物理弹球,弹球掉落在由两段线条组成的L形状上会有反弹效果。
"""
 
 
import random
 
import pygame
from pygame.key import *
from pygame.locals import *
from pygame.color import *
 
import pymunk
import pymunk.pygame_util


class BouncyBalls(object):
    """
     
    这个类实现一个简单的平台上有着随机掉落的弹球场景。
    """
    def __init__(self):
         
        self._space = pymunk.Space()           # 新建重力空间
        self._space.gravity = (0.0, -900.0)    # 重力加速度
 
        self._dt = 1.0 / 60.0                  # 这里应该是60分之一秒更新一次重力空间
        #  屏幕每一帧执行的物理刷新次数
        self._physics_steps_per_frame = 1

        # pygame 初始化
        pygame.init()
        self._screen = pygame.display.set_mode((600, 600))
        self._clock = pygame.time.Clock()

        self._draw_options = pymunk.pygame_util.DrawOptions(self._screen)
        print(self._draw_options)

        # 添加棍子,弹球碰到它会反弹
        self._add_static_scenery()

        # 所有的球在这个列表中
        self._balls = []

        # 主循环逻辑变量与产生球的时隔
        self._running = True
        self._ticks_to_next_ball = 10

    def run(self):
        """
         这里是场景的主要循环
        """
        
        while self._running:
            # 每帧执行几次物理计算过程?
            for x in range(self._physics_steps_per_frame):
                self._space.step(self._dt)

            self._process_events()
            self._update_balls()
            self._clear_screen()
            self._draw_objects()
            pygame.display.flip()
            # Delay fixed time between frames
            self._clock.tick(50)
            pygame.display.set_caption("fps: " + str(self._clock.get_fps()))
        pygame.quit()

    def _add_static_scenery(self):
        """
        创建静止不动的两根棍子
        """
        static_body = self._space.static_body
        static_lines = [pymunk.Segment(static_body, (111.0, 280.0), (407.0, 246.0), 0.0),
                        pymunk.Segment(static_body, (407.0, 246.0), (407.0, 343.0), 0.0)]
        for line in static_lines:
            line.elasticity = 0.95
            line.friction = 0.9
        self._space.add(static_lines)

    def _process_events(self):
        """
        Handle game and events like keyboard input. Call once per frame only.
        :return: None
        """
        for event in pygame.event.get():
            if event.type == QUIT:
                self._running = False
            elif event.type == KEYDOWN and event.key == K_ESCAPE:
                self._running = False
            elif event.type == KEYDOWN and event.key == K_p:
                pygame.image.save(self._screen, "bouncing_balls.png")

    def _update_balls(self):
        """
        每帧调用一次,创建球或者移出y坐标小于100的弹球。Create/remove balls as necessary. Call once per frame only.
        :return: None
        """
        self._ticks_to_next_ball -= 1
        if self._ticks_to_next_ball <= 0:
            self._create_ball()
            self._ticks_to_next_ball = 100
        # Remove balls that fall below 100 vertically
        balls_to_remove = [ball for ball in self._balls if ball.body.position.y < 100]
        for ball in balls_to_remove:
            self._space.remove(ball, ball.body)
            self._balls.remove(ball)

    def _create_ball(self):
        """
        创建一个物理 弹球
        """
        mass = 10
        radius = 25
        inertia = pymunk.moment_for_circle(mass, 0, radius, (0, 0))
        body = pymunk.Body(mass, inertia)
        x = random.randint(115, 350)
        body.position = x, 400
        shape = pymunk.Circle(body, radius, (0, 0))
        shape.elasticity = 0.95        # 弹性系数
        shape.friction = 0.9           # 摩擦系数
        self._space.add(body, shape)
        self._balls.append(shape)

    def _clear_screen(self):
        """
        清屏为白色
        """
        self._screen.fill(THECOLORS["white"])

    def _draw_objects(self):
        """
        画各个物体
        """
        self._space.debug_draw(self._draw_options)


if __name__ == '__main__':
    game = BouncyBalls()
    game.run()

以下是函数实现的,不过当小球离开屏幕时并没有把它删除,并且左边掉落的小球为什么会有瞬移现象出现呢?

import sys, random
import pygame
from pygame.locals import *
import pymunk
import pymunk.pygame_util

def add_static_L(space):
    body = pymunk.Body(body_type = pymunk.Body.STATIC) # 增加静态实体
    body.position = (300, 300)
    shape1 = pymunk.Segment(body, (-150, 0), (255, 0), 5)   # 此坐标是相对于(300,300)为原点的
    shape1.elasticity = 0.95        # 弹性系数
    shape1.friction = 0.9           # 摩擦系数
    
    shape2 = pymunk.Segment(body, (-150, 0), (-150, 50), 5) # y坐标相反
    shape2.elasticity = 0.95        # 弹性系数
    shape2.friction = 0.9           # 摩擦系数    
    
    space.add(shape1, shape2) # 增加到物理空间
    return shape1,shape2


def add_ball(space):
    mass = 1
    radius = 14
    moment = pymunk.moment_for_circle(mass, 0, radius) # 求一定质量和半径的小球的转动惯量,返回浮点数
     
    body = pymunk.Body(mass, moment)    # 新建刚体
    
    x = random.randint(120, 380)        # 随机x坐标
    body.position = x, 550              # 定位
    shape = pymunk.Circle(body, radius) # 设形状
    shape.elasticity = 0.95             # 弹性系数
    shape.friction = 0.9                # 摩擦系数
    space.add(body, shape)              # 放到物理空间     
    return shape

def main():
    pygame.init()
    screen = pygame.display.set_mode((600, 600))
    pygame.display.set_caption("自由落体小球")
    clock = pygame.time.Clock()

    space = pymunk.Space()
    space.gravity = (0.0, -900.0)

    lines = add_static_L(space)
    balls = []
    draw_options = pymunk.pygame_util.DrawOptions(screen) # 设定space内物体的渲染面

    ticks_to_next_ball = 10
    running = True
    while running:
        for event in pygame.event.get():
            if event.type in( QUIT,KEYDOWN,K_ESCAPE):
                running = False
                break                  

        ticks_to_next_ball -= 1
        if ticks_to_next_ball <= 0:
            ticks_to_next_ball = 25
            ball_shape = add_ball(space)
            balls.append(ball_shape)

        space.step(1/50.0)

        screen.fill((255,255,255))
        space.debug_draw(draw_options)

        pygame.display.flip()
        clock.tick(50)

    pygame.quit()

if __name__ == '__main__':
    main()

 

发表在 pymunk | pymunk物理引擎之掉落的弹球已关闭评论

Python物理沙盒测试程序pyphysicssandbox

"""
派物理沙盒是Pymunk的封装,可以用来模拟2D物理世界。设计的目标是用于学习编程入门。 安装方法:pip install pyphysicssandbox --user
"""
from

import *

window("Python物理沙盒测试程序", 400, 300)
gravity(0.0, 500.0)                     #  设定重力参数

b1          = ball((100, 10), 30)        
b1.color    = Color('green')
b1.friction = 0.25

b2       = static_ball((98, 100), 30)  # 静止的小球,接受碰撞检测
b2.color = Color('blue')

b3       = cosmetic_ball((198, 100), 50) # 装点门面的的小球,不接受碰撞检测
b3.color = Color('cyan')

box1       = static_rounded_box((0, 290), 400, 10, 3) # 最下面的地板,静止的
box1.color = Color('brown')

box2 = static_rounded_box((100,10), 50, 50, 5 ) # 上面品红色的圆角正方形
box2.color = Color('magenta')

tri1       = triangle((260, 35), (250, 35), (240, -15)) # 三角形
tri1.color = Color('red')

poly1       = polygon(((195, 35), (245, 35), (220, -15))) # 多边形
poly1.color = Color('blue')
poly1.wrap  = True

run()

print('完也! ')

 

发表在 physicssandbox | Python物理沙盒测试程序pyphysicssandbox已关闭评论

pymunk物理引擎基本例子

"""pymunk物理引擎基本例子
"""
import turtle
import pymunk
import pymunk.util
from pymunk import Vec2d
import math, sys, random

def main():
              
    space = pymunk.Space()
    space.gravity = (0.0, -900.0)
    
    ## Balls
    balls = []
    balls_for_render = []
          
    ticks_to_next_ball = 10
    for x in range(5008880):            
        ticks_to_next_ball -= 1
        if ticks_to_next_ball <= 0:
            ticks_to_next_ball = 10000
            mass = 10
            radius = 25
            inertia = pymunk.moment_for_circle(mass, 0, radius, (0,0))
            body = pymunk.Body(mass, inertia)
            x = random.randint(-200,200)
            body.position = x, 400
            shape = pymunk.Circle(body, radius, Vec2d(0,0))
            
            space.add(body, shape)
            balls.append(shape)
            # 以下代码是lixingqiu加的
            b = turtle.Turtle(visible=False,shape='circle')
            b.penup()
            b.shapesize(radius/10,radius/10) # 海龟画图中小球默认半径为10
            b.goto(x, 400)
            b.showturtle()
            balls_for_render.append(b)
        
        
        balls_to_remove = []
        
        for i in range(len(balls)):
            ball = balls[i]
            if ball.body.position.y < 0:
                balls_to_remove.append(i)# 加到待移除列表
            b = balls_for_render[i]
            b.goto(ball.body.position)
                
        for i in balls_to_remove:
            space.remove(balls[i], balls[i].body)
            balls.pop(i)            
            balls_for_render.pop(i)

        if len(balls) >= 1:
           v = balls[0].body.position
           print("(in on_draw): point = %.2f, %.2f" % (v.x,v.y))

        ### Update physics
        for x in range(1):
            space.step(1/50.0)
        

if __name__ == '__main__':
    width,height = 600,600
    screen = turtle.Screen()
    screen.delay(0)
    screen.setup(width,height)
    screen.title("pymunk物理引擎基本例子")
    
    sys.exit(main())

 

发表在 pymunk | pymunk物理引擎基本例子已关闭评论

海龟画图和pymunk物理引擎模拟小球自由落体


以下是部分代码预览:

"""海龟画图和pymunk物理引擎模拟小球自由落体。
pymunk是python的一个2d物理引擎,在官网上说它可以和pygame等结合起来一起使用。
看到在Arcade街机模块里使用后,想到能不能在海龟画图里使用。
这是因为只是把海龟画图用来渲染,而受重力的魂还是由于物理引擎的作用。
测试后,成功。 www.lixingqiu.com
"""
import pymunk                       # 导入pymunk模块
import turtle                       # 导入海龟模块,用它来渲染刚体

def spawn(x,y):
    ball_shape = turtle.Turtle(shape='circle',visible=False)
    ball_shape.shape("绿球.gif")
    ball_shape.penup()
    ball_shape.color("blue")
        
    mass = 1
    radius = 25
    moment = pymunk.moment_for_circle(mass, 0, radius) # 求一定质量和半径的小球的转动惯量,返回浮点数
    
width,height = 600,600
balls_list = []

screen = turtle.Screen()                 # 新建海龟窗口,用于渲染形状的
screen.delay(0)
screen.title("海龟画图和pymunk物理引擎模拟小球自由落体,作者:李兴球")
screen.setup(600,600)
screen.bgcolor("cyan")
screen.addshape("绿球.gif")

space = pymunk.Space()                   # 设定重力空间
space.gravity = 0,-30                    # 设置重力参数

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pymunk, python, turtle | 海龟画图和pymunk物理引擎模拟小球自由落体已关闭评论

Python中途岛海战街机1943模拟_A Simple Version of Midway Island Naval Warfare with Pthon for Easy Learning

以下是部分代码预览:

"""
A Simple Version of Midway Island Naval Warfare with Pthon for Easy Learning by lixingqiu
这个射击游戏是使用Arcade模块制作的。这个版本是核心版本,演示了爆炸效果,类的继承,按键检测等。
其中滚动的背景是使用两张图片制作的,它们相隔SCREEN_HEIGHT的高度。如果图片的top到了最底下,也就是坐标为0了,那么它就瞬间移到最顶上去。
要注意Arcade的坐标系统和数学中的坐标系统一样,在本游戏中是以左下角为原点,y轴正向上。在Pygame中则是左上角为原点,y轴正向下。
"""

__author__ = "lixingqiu"
__date__ = "2019/3/13"
__url__ = "https://www.lixingqiu.com/?p=209"
__qq__ = "406273900"

import os
import random
import arcade

SPRITE_SCALING = 1.0

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "A Simple Version of Midway Island Naval Warfare with Pthon for Easy Learning(Python中途岛海战街机模拟)"
ENEMY_COUNT = 100
MOVEMENT_SPEED  = 5

class Explosion(arcade.Sprite):
    """ 创建可爆炸的角色 create explosion sprite""" 

    def __init__(self, texture_list,x,y):
        """texture_list是已经load了的造型列表"""
        super().__init__()

        self.center_x = x
        self.center_y = y
        # 第一帧
        self.current_texture = 0      # 这是造型索引号
        self.textures = texture_list  # 这是每帧图片列表
        self.set_texture(self.current_texture)

    def update(self):

        # 更新每帧的图片,到了最后一帧后就会删除自己。
        self.current_texture += 1
        if self.current_texture < len(self.textures):
            self.set_texture(self.current_texture)
        else:
            self.kill()

class Bullet(arcade.Sprite):
    """子弹类,继承自Arcade自带的角色类,它从飞机的坐标射出"""
    def __init__(self,image,plane):
        super().__init__(image)
        self.center_x = plane.center_x
        self.center_y = plane.center_y
        self.change_y = 20        

    def update(self):
        """每帧更新坐标 update coordinates"""
        self.center_x += self.change_x
        self.center_y += self.change_y
        if self.bottom >  SCREEN_HEIGHT: self.kill()
        
class Background(arcade.Sprite):
    
    def __init__(self,image):
        super().__init__(image)    
        self.change_y = -10       

    def update(self):
        self.center_x += self.change_x
        self.center_y += self.change_y
        if self.top <=0 : self.bottom = SCREEN_HEIGHT
        
class Enemy(arcade.Sprite):
    def __init__(self,image):
        super().__init__(image)
        self.center_x = random.randrange(SCREEN_WIDTH)
        self.center_y = random.randrange(SCREEN_HEIGHT,SCREEN_HEIGHT*30)

    def update(self):
        
        if self.top<=0:self.kill()
            
        
class MyGame(arcade.Window):
    """ 应用程序主要类. """

    def __init__(self, width, height, title):

        super().__init__(width, height, title)

        # 角色列表定义
        self.all_sprites_list = None
        self.enemy_list = None

        # 定义玩家的相关变量 
        self.score = 0
        self.player_sprite = None

    def start_new_game(self):
        """ 设置与初始化游戏 """            
        sea_image = "images/midway/sea.png"
        # Setting a Fixed Background 设置不动的背景 To cover up rolling background cracks
        self.background = arcade.Sprite(sea_image)
        self.background.center_x = SCREEN_WIDTH // 2
        self.background.bottom = 0
        
        # 设置滚动背景,两个最先画的角色往下移,移到一定坐标就到上面去
        self.background1 = Background(sea_image)
        self.background1.center_x = SCREEN_WIDTH // 2
        self.background1.bottom = 0
        self.all_sprites_list.append(self.background1)
        
        self.background2 = Background(sea_image)
        self.background2.center_x = SCREEN_WIDTH // 2
        self.background2.bottom = SCREEN_HEIGHT  
        self.all_sprites_list.append(self.background2)

        # 1943logo
        self.logo_1943 = arcade.Sprite("images/midway/1943Logo2.png")
        self.logo_1943.center_x  = SCREEN_WIDTH // 2
        self.logo_1943.center_y  = SCREEN_HEIGHT // 2
        self.interval = 60
        self.interval_counter = 0    

    def on_key_release(self, key, modifiers):
        """鼠标松开事件 """
        if self.player_sprite.health <=0 :return
        if key == arcade.key.W or key == arcade.key.S:
            self.player_sprite.change_y = 0
        elif key == arcade.key.A or key == arcade.key.D:
            self.player_sprite.change_x = 0


              
class Cover(arcade.Window):
    """封面类"""
    def __init__(self, width, height, title):

        super().__init__(width, height, title)


        
    def on_key_press(self, key, modifiers):
        """鼠标按键事件 """

        if key == arcade.key.SPACE: # 按空格键关闭窗口
            self.close()
                                        
    def update(self,delta_time):
        self.demo_plane.update()
        self.demo_plane.update_animation()
        
                                        
    def on_draw(self):
        """        渲染屏幕        """

        # 开始渲染,此命令要在所有重画命令之前
        arcade.start_render()
        self.background.draw()
        self.demo_plane.draw()         
        

def main():

    cover = Cover(800, 600, SCREEN_TITLE)
    cover.setup()
    arcade.run()
    
    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
    window.start_new_game()
    arcade.run()


if __name__ == "__main__":
    main()

 

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, python | Python中途岛海战街机1943模拟_A Simple Version of Midway Island Naval Warfare with Pthon for Easy Learning已关闭评论

有封面和过关界面的_小昆虫接金币闯关 _Python迷宫跳跃型闯关游戏模版

以下是部分代码预览:

"""
小昆虫接金币闯关,这是用Python Arcade街机模块制作的一个多关卡小游戏。
相对于前一个版本,这个游戏有开始界面,不过是用海龟画图模块制作的。
每过一关还有“按空格键进入下一关的“的过关提示画面。

全部关卡过完后,有“通关界面”。本游戏需要先安装arcade模块和有相关素材才能正确运行。
作者是李兴球。
"""

import arcade
import time

SPRITE_SCALING = 1                    # 定义缩放比例
SCREEN_WIDTH = 960                    # 定义所渲染的屏幕宽度 
SCREEN_HEIGHT = 768                   # 定义所渲染的屏幕高度 
SCREEN_TITLE = "有封面和过关界面的_小昆虫接金币闯关_lixingqiu "
SPRITE_PIXEL_SIZE = 64               # 地图方块尺寸 

# 定义物理常数 
MOVEMENT_SPEED = 5
JUMP_SPEED = 23
GRAVITY = 1.1

class MyGame(arcade.Window):
    """ 继承自窗口的游戏类. """

    def __init__(self):
        """
        初始化方法
        """
        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
        
        # 定义角色列表
        self.wall_list = None
        self.player_list = None
        self.coin_list = None

        # 定义玩家相关变量
        self.score = 0
        self.player_sprite = None

        self.physics_engine = None         
        self.game_over = False
        self.last_time = None       # 用来算fps的上次时间变量
        self.frame_count = 0        # 帧计数器
        self.fps_message = None     # fps字符串

        self.level = 1              # 开始关卡号
        self.max_level = 3          # 关卡数量

    def setup(self):
        """ 设置与初始化变量的值. """
        self.status = "level_end"
        self.level_cover = arcade.Sprite("过关界面.png")
        self.level_cover.textures.append(arcade.load_texture("通关界面.png"))
        self.level_cover.center_x = SCREEN_WIDTH//2
        self.level_cover.center_y = SCREEN_HEIGHT//2
        
        
        # 角色列表初始化
        self.player_list = arcade.SpriteList()
        self.coin_list = arcade.SpriteList()

        # 玩家操作的角色实例化,这里是一只昆虫
        self.player_sprite = arcade.Sprite("images/lixingqiu.png", SPRITE_SCALING*0.5)

        # 给昆虫设定坐标
        self.player_sprite.center_x = 128
        self.player_sprite.center_y = 64
        self.player_list.append(self.player_sprite)

        self.load_level(self.level) # 加载第一关

        self.game_over = False
   

    def on_draw(self):
        """
        渲染屏幕
        """
    
        
    def on_key_press(self, key, modifiers):
        """
        当按键时调用此方法
        """

    def on_key_release(self, key, modifiers):
        """
        当松开键时调用此方法
        """
        if key == arcade.key.LEFT or key == arcade.key.RIGHT:
            self.player_sprite.change_x = 0

    def update(self, delta_time):
        """ 移动与游戏的逻辑,这个方法不断地执行,如果本关金币数加载完了,那么此关结束 """

            
def display_cover(cover_image):
    """显示封面"""
    import turtle
    screen = turtle.Screen()
    screen.bgpic(cover_image)
    screen.setup(SCREEN_WIDTH,SCREEN_HEIGHT)
    screen.title(SCREEN_TITLE)
    screen.onkeypress(lambda:screen.bye(),"space") # 绑定空格键
    screen.listen()
    screen.mainloop()
    
def main():
     
    display_cover("封面.png") 
    window = MyGame()
    window.setup()
    arcade.run()

if __name__ == "__main__":
    main()

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, python | 有封面和过关界面的_小昆虫接金币闯关 _Python迷宫跳跃型闯关游戏模版已关闭评论

Python街机模块制作的巫婆和仙女漫游太阳系小故事交互动画by lixingqiu。

这是一个交互动画,本人用python的海龟模块,Pygame模块做过类似的动画,现在又用arcade模块做一下。不过编了个小故事。
以下是部分代码预览:

"""
巫婆和仙女漫游太阳系小故事动画。

仙女教她的外婆仙术,可是她的外婆由于年纪大了,只学了一半,总也飞不起来。所以仙女送了外婆一把天方夜谭里的神扫帚。
就这样,她们一起离开了地球,在太阳系漫游的不亦乐乎。可是,她们也要呼吸啊,带的氧气不多了。还好,西天取经回来的斗战圣佛孙悟空在暗中已经明察秋毫。
他是不是地变一瓶氧气给她们使用。聪明的仙女一子就发现了太阳系会冒出氧气瓶,她们一起收集了一些氧气,造访了水星、金星、火星、木星、土星、天王星之后,还是玩厌了。
空荡荡的太阳系好无聊,其它星球都不适合人也不适合地神仙玩,所以她们想回地球。可是那时候地球已经被邪恶的宇宙超级大BOSS灭霸给锁住了,她们接近地球时只会被撞死。
还好,有惊奇队长和神奇女侠来帮忙了。惊奇队长安装了一个按扭,只要碰到按扭,那么太阳系行星和太阳的时空就会变慢。
神奇女侠送了神秘香蕉,只要吃了香蕉就能进入地球了。快来玩下这个游戏吧,操作方法:
按上下左右方向箭头或awsd箭头一个角色碰触按钮,让另一个角色顺利的吃到香蕉,然后一起飞回地球。
 
"""
import time
import math
import arcade
import random

SCREEN_WIDTH = 1350
SCREEN_HEIGHT = 780
SCREEN_TITLE = "Python街机动画:巫婆和仙女漫游太阳系动画,作者:李兴球"
MOVEMENT_SPEED = 5

class Planet(arcade.Sprite):
   
    def __init__(self,image,position,period):
        """image:造型图片,position:初始坐标,初始角度"""
        super().__init__(image)
        x,y = position
        self.center_x = SCREEN_WIDTH / 2
        self.center_y = SCREEN_HEIGHT / 2           
        self.a = y * 1.5                        # 长半轴
        self.b = y                              # 短半轴
        self.period = period        
        self.direction = 90
        
class Oxygen(arcade.Sprite):
    """氧气瓶类"""
    def __init__(self,image):
        super().__init__(image,0.5)
        self.center_x = random.randrange(SCREEN_WIDTH)
        self.center_y = random.randrange(SCREEN_HEIGHT)
        self.alpha = 80
        
    
class MyGame(arcade.Window):
    """
    继承自窗口的MyGame类.
    """
    timespace = 1                                             # 游戏的时空变量
    can_home = False                                          # 能回家的逻辑变量
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        self.frame_counter = 0                                # 帧计数器
        self.planet_list = arcade.SpriteList()                # 新建角色列表,以便统一渲染
        self.all_stars_list = arcade.SpriteList()             # 所有星星列表,包括恒星和行星
        self.oxygen_list = arcade.SpriteList()                # 氧气瓶列表
        self.astronaut_list = arcade.SpriteList()             # 宇航员列表
        
    def setup(self):
        """ 这里是对游戏中的各个对象进行设置 """

        # 背景角色生成
        self.background = arcade.Sprite("bg.png")
        self.background.center_x = SCREEN_WIDTH / 2
        self.background.center_y = SCREEN_HEIGHT / 2

        # 太阳角色生成
        self.sun = arcade.AnimatedTimeSprite()                # 新建动画时序角色
        self.sun.center_x = SCREEN_WIDTH//2
        self.sun.center_y = SCREEN_HEIGHT//2   
            
        # 宇航员角色生成
        self.astronaut1 = arcade.Sprite("princess.png",0.25)  # 宇航员1角色,第二个参数是比例
        self.astronaut1.status = "live"                       # 自定义属生,
        self.astronaut1.oxygens = 1000                        # 自定义属性,氧气数量
        self.astronaut1.center_x = 100
        self.astronaut1.center_y = 100
        self.astronaut2 = arcade.Sprite("witch.png",0.25)     # 宇航员2角色,第二个参数是比例
        self.astronaut2.status = "live"                       # 自定义属生,
        self.astronaut2.oxygens = 1000                        # 自定义属性,氧气数量
        self.astronaut2.center_x = SCREEN_WIDTH-100
        self.astronaut2.center_y = SCREEN_HEIGHT-100
        self.astronaut_list.append(self.astronaut1)
        self.astronaut_list.append(self.astronaut2)

            
    def on_key_release(self, key, modifiers):
        """松开按键. """
            
        
    def update(self, x):
        """每帧更新游戏内在逻辑"""       

    
    def on_draw(self):
        """
        渲染屏幕        """            
 

def main():
    """ Main method """
    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, python | Python街机模块制作的巫婆和仙女漫游太阳系小故事交互动画by lixingqiu。已关闭评论

小昆虫接金币闯关

以下是部分代码预览:

"""
小昆虫接金币闯关,这是用Python Arcade街机模块制作的一个多关卡小游戏。游戏虽然简单,但是它演示一个多关卡房间游戏的基本框架。
本游戏首先需要加载tmx格式的地图,它是由Tiled软件制作的。共有3个关卡,小昆虫接完所有道具后自动进入下一关卡。
下一个版本实现昆虫的造型能左右分开,再下一个版本安排一扇门,当接完所有道具后门就显示出来。小昆虫碰到了门才能进入下一关。
再下一个版本实现可移动的敌人,小昆虫碰到敌人游戏就会失败。再下一个版本加一个封面和结尾,剧终。

"""

import arcade
import time

SPRITE_SCALING = 1                    # 定义缩放比例
SCREEN_WIDTH = 960                    # 定义所渲染的屏幕宽度 
SCREEN_HEIGHT = 768                   # 定义所渲染的屏幕高度 
SCREEN_TITLE = "Python平铺地图多关卡示例_ "
SPRITE_PIXEL_SIZE = 64               # 地图方块尺寸 

# 定义物理常数 
MOVEMENT_SPEED = 5
JUMP_SPEED = 23
GRAVITY = 1.1

class MyGame(arcade.Window):
    """ 继承自窗口的游戏类. """

    def __init__(self):
        """
        初始化方法
        """
        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
        
        # 定义角色列表
        self.wall_list = None
        self.player_list = None
        self.coin_list = None

        # 定义玩家相关变量
        self.score = 0
        self.player_sprite = None

        self.physics_engine = None         
        self.game_over = False
        self.last_time = None       # 用来算fps的上次时间变量
        self.frame_count = 0        # 帧计数器
        self.fps_message = None     # fps字符串

        self.level = 1              # 开始关卡号
        self.max_level = 3          # 关卡数量

    def setup(self):
        """ 设置与初始化变量的值. """

        # 角色列表初始化
        self.player_list = arcade.SpriteList()
        self.coin_list = arcade.SpriteList()

        # 玩家操作的角色实例化,这里是一只昆虫
        self.player_sprite = arcade.Sprite("images/lixingqiu.png", SPRITE_SCALING*0.5)

        # 给昆虫设定坐标
        self.player_sprite.center_x = 128
        self.player_sprite.center_y = 64
        self.player_list.append(self.player_sprite)

        self.load_level(self.level) # 加载第一关

        self.game_over = False
   

    def on_draw(self):
        """
        渲染屏幕
        """
        self.frame_count += 1      # 帧计数器

        # 开始渲染屏幕
        arcade.start_render()

    def on_key_press(self, key, modifiers):
        """
        当按键时调用此方法
        """
        if key == arcade.key.UP:
            if self.physics_engine.can_jump():          # 这里是检测有没有在地面
                self.player_sprite.change_y = JUMP_SPEED
        elif key == arcade.key.LEFT:
            self.player_sprite.change_x = -MOVEMENT_SPEED
        elif key == arcade.key.RIGHT:
            self.player_sprite.change_x = MOVEMENT_SPEED

    def on_key_release(self, key, modifiers):
        """
        当松开键时调用此方法
        """
        if key == arcade.key.LEFT or key == arcade.key.RIGHT:
            self.player_sprite.change_x = 0

    def update(self, delta_time):
        """ 移动与游戏的逻辑,这个方法不断地执行,如果本关金币数加载完了,那么此关结束 """

def main():
    window = MyGame()
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, python | 小昆虫接金币闯关已关闭评论

arcade制作动态背景_使用面向对象编程方法继承Window类

以下是部分代码预览:

"""本程序会不断地重画背景图片,定义了一个游戏类"""

import arcade

SCREEN_WIDTH = 500
SCREEN_HEIGHT = 685
SCREEN_TITLE = "arcade制作动态背景_使用面向对象编程方法继承Window类"

class MyGame(arcade.Window):    
    def __init__(self):         
        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
        self.backgrounds = arcade.AnimatedTimeSprite()        # 新建时序角色
        
    def on_draw(self):
        """每帧都会自动重画所有对象 """
        arcade.start_render()    
        self.backgrounds.draw()
        
    def update(self,delta_time):
         
        self.backgrounds.update_animation()  # 更新动画
        

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, python | arcade制作动态背景_使用面向对象编程方法继承Window类已关闭评论

实现同样的功能Pygame和Arcade所用代码量对比

实现同样的功能Pygame和Arcade所用代码量对比,左边是Pygame代码,右边是Arcade代码。它们都实现在一个窗口显示Hi there这串文本。

import pygame
from pygame.locals import *

# 初始化pygame
pygame.init()
screen = pygame.display.set_mode((240, 140))
screen.fill((00,255,255))
pygame.display.set_caption('基本程序示例')

# 把文本渲染到屏幕                
font = pygame.font.Font(None, 36)
text = font.render("Hello There", 1, (10, 10, 10))
screen.blit(text, (0, 0))

# 事件循环
running = True
while running:
    for event in pygame.event.get():
        if event.type == QUIT:
              running = False
    pygame.display.flip()
pygame.quit()

import arcade

arcade.open_window(240,140,"这里是标题")              # 打开窗口
arcade.set_background_color(arcade.color.CYAN)     # 设置背景颜色
arcade.start_render()                              # 开始渲染
arcade.draw_text( "Hi there", 100, 100, arcade.color.BLACK,48)
arcade.finish_render()                             # 结束渲染
arcade.run()                                             # 进入主循环


 

发表在 arcade | 实现同样的功能Pygame和Arcade所用代码量对比已关闭评论

Arcade模块和Pygame模块总结

 

序号
名称
Arcade
Pygame
1
新建角色
直接用Sprite类带上图形文件参数
需要继承pygame.sprite.Sprite自己写代码
2
游戏循环
封装在run命令
需要自己写循环进行事件检测等
3
缩放角色
非常简单,设定比例即可。
稍微复杂
4
旋转角色
非常简单,设定角度即可
稍微复杂,需要自己写代码
5
坐标模式
左下角为坐标原点,和数学保持一致
左上角为坐标原点
6
命名规范
更加符合人类思维,如打开窗口,直接用open_window
pygame打开窗口用的是pygame.display.set_mode命令。
7
逻辑和显示
分离
倾向于将两者放在同一个游戏循环中。
8
像素操作/CDOM/MIDI
不支持
支持
9
动画角色
AnimatedTimeSprite类和
AnimatedWalkingSprite类供使用
需要继承pygame.sprite.Sprite
自己写一系列代码实现动画角色
10
surface概念
没有此概念
有这个概念,层面之间可以合成
11
平铺地图
内置Tiled地图相关操作
没有相关命令
12
物理引擎
有简易型的物理引擎
不支持
发表在 arcade | Arcade模块和Pygame模块总结已关闭评论

Arcade最简收集金币小程序

这个程序演示了用Arcade街机模块制作一个收集金币的游戏。通过鼠标操作角色去碰撞金币,金币就会消失。运用了角色实例化,角色列表实例化,鼠标移动事件,碰撞检测等“技术”。


以下是部分代码预览:

import arcade
import random

SCREEN_WIDTH = 800                                                    #  常量定义,屏幕宽度
SCREEN_HEIGHT = 600                                                   #   常量定义,屏幕高度
SCREEN_TITLE = "Arcade最简收集金币小程序_作者:李兴球"                # 常量定义,屏幕标题

class MyGame(arcade.Window):
    """    继承自窗口类的游戏类,在具体的游戏中,重写以下方法,删除不需要重写的方法。    """

    def __init__(self, width, height, title):
        super().__init__(width, height, title)                      #  调用父类的初始化方法新建一个窗口
        arcade.set_background_color(arcade.color.AMAZON)            #  设置背景颜色为亚马逊绿
        
    def setup(self):
        """ 这个方法是在实例化Mygame后对游戏进行一些设置。 """
        self.player = arcade.Sprite("characterx.png")               # 给游戏添加一个玩家控制的角色  
        self.coin_list = arcade.SpriteList()                        # 实例化一个金币列表
        for i in range(50):
            coin = arcade.Sprite("coin_01x.png")                    # 实例化一枚金币
            coin.center_x = random.randrange(SCREEN_WIDTH)
            coin.center_y = random.randrange(SCREEN_HEIGHT)
            self.coin_list.append(coin)
            

    def on_draw(self):
        """ 渲染屏幕  ,帧率为60左右,即每60份之一秒会自动调用此方法     """        
        arcade.start_render()                      # 此命令会用背景色填充屏幕,然后可以在这个代码下用draw命令画其它角色        
        self.coin_list.draw()                      # 先画所有金币
        self.player.draw()                         # 再画玩家

    def update(self, delta_time):
        """ 所有的角色移动等游戏逻辑都在这里编写代码   """

    
    def on_mouse_motion(self, x, y, delta_x, delta_y):
        """ 当鼠标移动时会自动地调用此方法 """


def main():
    """主要的函数"""
    game = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)  # 实例化一个游戏
    game.setup()                                              # 对游戏进行设置
    arcade.run()                                              # 进入循环

if __name__ == "__main__":  
      main()

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, python | Arcade最简收集金币小程序已关闭评论

arcade最简单的鼠标移动角色

以下是部分代码预览:

import arcade
 
class MyGame(arcade.Window):     

    def __init__(self):         
        super().__init__(600, 600, "arcade最简单的鼠标移动角色_lixingqiu")
        # 设置背景颜色
        arcade.set_background_color(arcade.color.AMAZON)
        # 实例化玩家
        self.player = arcade.Sprite("character.png")
        self.player.center_x = 50
        self.player.center_y = 50
        
    def on_draw(self):
        """每帧都会自动重画所有对象 """
        arcade.start_render()    
 
 
    def on_mouse_motion(self, x, y, dx, dy):
        """当鼠标指针移动时会自动调用此方法""" 


if __name__ == "__main__":
    
    window = MyGame()   
    arcade.run() 

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, python | arcade最简单的鼠标移动角色已关闭评论

Pygame最简单的鼠标移动角色

import pygame
from pygame.locals import *

class Player(pygame.sprite.Sprite):
    
    def __init__(self,image):        
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(image)
        self.rect = self.image.get_rect()
        self.screen = pygame.display.get_surface()
        
    def update(self):
        x,y = pygame.mouse.get_pos()
        self.rect.center = x,y
        
    def draw(self):
        self.screen.blit(self.image,self.rect)
        
if __name__ == "__main__":    
           
    pygame.init()

    screen = pygame.display.set_mode((600,600))
    pygame.display.set_caption("Pygame最简单的鼠标移动角色_lixingqiu")

    player = Player("character.png")

    running = True
    while running:
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False
        
        player.update()        
        screen.fill((0,0,0))
        player.draw()
        pygame.display.flip()

    pygame.quit()

发表在 pygame | Pygame最简单的鼠标移动角色已关闭评论

Arcade旋转角色简易示例

"""Arcade旋转角色简易示例,
本程序演示新建一个角色,给它设定了两个造型。注意在Arcade中是以左下角为坐标原点。"""

import arcade

arcade.open_window(480,360,"Arcade旋转角色简易示例_lixingqiu")   # 打开窗口
arcade.set_background_color(arcade.color.CYAN)     # 设置背景颜色
player = arcade.Sprite("images/character.png", 0.5)# 新建角色

player.append_texture( arcade.load_texture("images/bumper.png") )# 添加造型
player.set_texture( 0 )                            # 设置为第1个造型

player.center_x  = 100                             # 角色x坐标
player.center_y  = 100                             # 角色y坐标 
player.angle= 90                                   # 角色的角度 
  
arcade.start_render()                              # 开始渲染
player.draw()                                      # 画角色
arcade.finish_render()                             # 结束渲染
arcade.run()                                       # 进入主循环

 

发表在 arcade, python | Arcade旋转角色简易示例已关闭评论

在屏幕上显示一个计时器

"""
在屏幕上显示一个计时器
"""

import arcade

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "计时器示例"


class MyGame(arcade.Window):
    """
    主要应用程序类
    """

    def __init__(self):
        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
        self.total_time = 0.0

    def setup(self):
        """
        对应用程序进行设置,如设置背景颜色
        """
        arcade.set_background_color(arcade.color.WHITE)
        self.total_time = 0.0

    def on_draw(self):
        """ 使用这个函数在屏幕上重画所有对象. """

        # 开始渲染
        arcade.start_render()

        # 计算分钟
        minutes = int(self.total_time) // 60

        # 通过求余计算秒数
        seconds = int(self.total_time) % 60

        # 合成输出字符串
        output = f"Time: {minutes:02d}:{seconds:02d}"

        # 画到屏幕上去
        arcade.draw_text(output, 300, 300, arcade.color.BLACK, 30)

    def update(self, delta_time):
        """
        所有的游戏逻辑在这里编写,如角色的移动,方向的改变,碰撞检测,本例只是统计游戏时间。
        """
         
        self.total_time += delta_time


def main():
    window = MyGame()
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()

 

发表在 arcade | 在屏幕上显示一个计时器已关闭评论

Arcade模版程序

"""
Arcade模版程序,当学会了面向对象编程后用此模版。

"""
import arcade

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Arcade模版程序"


class MyGame(arcade.Window):
    """
    继承自窗口类的游戏类,在具体的游戏中,重写以下方法,删除不需要重写的方法即可。
    """

    def __init__(self, width, height, title):
        super().__init__(width, height, title)

        arcade.set_background_color(arcade.color.AMAZON)

        # 定义游戏的一些属性,如定义角色,定义角色列表

    def setup(self):
        # 实例化游戏中的角色与角色列表
        pass

    def on_draw(self):
        """
        渲染屏幕
        """

        # 此命令会用背景色填充屏幕,然后可以在这个代码下用draw命令画其它角色
        arcade.start_render()


    def update(self, delta_time):
        """
        所有的角色移动等游戏逻辑都在这里编写代码
        """
        pass

    def on_key_press(self, key, key_modifiers):
        """
        当按键时调用此方法

        以下是按键列表:
        
Arcade街机模块按键码常量定义
""" pass def on_key_release(self, key, key_modifiers): """ 当松开键时调用此方法 """ pass def on_mouse_motion(self, x, y, delta_x, delta_y): """ 当鼠标移动时调用此方法 """ pass def on_mouse_press(self, x, y, button, key_modifiers): """ 当按鼠标键时调用此方法 """ pass def on_mouse_release(self, x, y, button, key_modifiers): """ 当松开鼠标键时调用此方法 """ pass def main(): """ 主要的方法""" game = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE) game.setup() arcade.run() if __name__ == "__main__": main()

 

发表在 arcade, python | Arcade模版程序已关闭评论

Arcade街机模块按键码常量定义

"""
Arcade街机模块按键码常量定义
"""

# Key modifiers
# Done in powers of two, so you can do a bit-wise 'and' to detect
# multiple modifiers.
MOD_SHIFT = 1       # 上档键
MOD_CTRL = 2        # 控制键
MOD_ALT = 4         # 变换键
MOD_CAPSLOCK = 8    # 大小写切换键
MOD_NUMLOCK = 16    # 数字锁定键
MOD_WINDOWS = 32
MOD_COMMAND = 64
MOD_OPTION = 128
MOD_SCROLLLOCK = 256 # 滚动锁定键
MOD_ACCEL = 2

# 按键
BACKSPACE = 65288
TAB = 65289
LINEFEED = 65290
CLEAR = 65291
RETURN = 65293
ENTER = 65293
PAUSE = 65299
SCROLLLOCK = 65300
SYSREQ = 65301
ESCAPE = 65307
HOME = 65360     #  回家键
LEFT = 65361     # 向左方向箭头按键码
UP = 65362       # 向上方向箭头按键码
RIGHT = 65363    # 向右方向箭头按键码
DOWN = 65364     # 向下方向箭头按键码
PAGEUP = 65365
PAGEDOWN = 65366
END = 65367
BEGIN = 65368
DELETE = 65535
SELECT = 65376
PRINT = 65377
EXECUTE = 65378
INSERT = 65379
UNDO = 65381
REDO = 65382
MENU = 65383
FIND = 65384
CANCEL = 65385
HELP = 65386
BREAK = 65387
MODESWITCH = 65406
SCRIPTSWITCH = 65406
MOTION_UP = 65362
MOTION_RIGHT = 65363
MOTION_DOWN = 65364
MOTION_LEFT = 65361
MOTION_NEXT_WORD = 1
MOTION_PREVIOUS_WORD = 2
MOTION_BEGINNING_OF_LINE = 3
MOTION_END_OF_LINE = 4
MOTION_NEXT_PAGE = 65366
MOTION_PREVIOUS_PAGE = 65365
MOTION_BEGINNING_OF_FILE = 5
MOTION_END_OF_FILE = 6
MOTION_BACKSPACE = 65288
MOTION_DELETE = 65535
NUMLOCK = 65407
NUM_SPACE = 65408
NUM_TAB = 65417
NUM_ENTER = 65421
NUM_F1 = 65425
NUM_F2 = 65426
NUM_F3 = 65427
NUM_F4 = 65428
NUM_HOME = 65429
NUM_LEFT = 65430
NUM_UP = 65431
NUM_RIGHT = 65432
NUM_DOWN = 65433
NUM_PRIOR = 65434
NUM_PAGE_UP = 65434
NUM_NEXT = 65435
NUM_PAGE_DOWN = 65435
NUM_END = 65436
NUM_BEGIN = 65437
NUM_INSERT = 65438
NUM_DELETE = 65439
NUM_EQUAL = 65469
NUM_MULTIPLY = 65450
NUM_ADD = 65451
NUM_SEPARATOR = 65452
NUM_SUBTRACT = 65453
NUM_DECIMAL = 65454
NUM_DIVIDE = 65455

# 在小键盘上的数字键
NUM_0 = 65456
NUM_1 = 65457
NUM_2 = 65458
NUM_3 = 65459
NUM_4 = 65460
NUM_5 = 65461
NUM_6 = 65462
NUM_7 = 65463
NUM_8 = 65464
NUM_9 = 65465

F1 = 65470
F2 = 65471
F3 = 65472
F4 = 65473
F5 = 65474
F6 = 65475
F7 = 65476
F8 = 65477
F9 = 65478
F10 = 65479
F11 = 65480
F12 = 65481
F13 = 65482
F14 = 65483
F15 = 65484
F16 = 65485
LSHIFT = 65505
RSHIFT = 65506
LCTRL = 65507
RCTRL = 65508
CAPSLOCK = 65509
LMETA = 65511
RMETA = 65512
LALT = 65513
RALT = 65514
LWINDOWS = 65515
RWINDOWS = 65516
LCOMMAND = 65517
RCOMMAND = 65518
LOPTION = 65488
ROPTION = 65489
SPACE = 32
EXCLAMATION = 33
DOUBLEQUOTE = 34
HASH = 35
POUND = 35
DOLLAR = 36
PERCENT = 37
AMPERSAND = 38
APOSTROPHE = 39
PARENLEFT = 40
PARENRIGHT = 41
ASTERISK = 42
PLUS = 43
COMMA = 44
MINUS = 45
PERIOD = 46
SLASH = 47

# 在主键盘上的数字键
KEY_0 = 48
KEY_1 = 49
KEY_2 = 50
KEY_3 = 51
KEY_4 = 52
KEY_5 = 53
KEY_6 = 54
KEY_7 = 55
KEY_8 = 56
KEY_9 = 57
COLON = 58
SEMICOLON = 59
LESS = 60
EQUAL = 61
GREATER = 62
QUESTION = 63
AT = 64
BRACKETLEFT = 91
BACKSLASH = 92
BRACKETRIGHT = 93
ASCIICIRCUM = 94
UNDERSCORE = 95
GRAVE = 96
QUOTELEFT = 96
A = 97
B = 98
C = 99
D = 100
E = 101
F = 102
G = 103
H = 104
I = 105
J = 106
K = 107
L = 108
M = 109
N = 110
O = 111
P = 112
Q = 113
R = 114
S = 115
T = 116
U = 117
V = 118
W = 119
X = 120
Y = 121
Z = 122
BRACELEFT = 123
BAR = 124
BRACERIGHT = 125
ASCIITILDE = 126

 

发表在 arcade | Arcade街机模块按键码常量定义已关闭评论

Arcade街机平铺地图多关卡示例

以下是部分代码预览:

"""
Arcade街机平铺地图多关卡示例
本程序加载tmx地图,生成关卡,根据角色到达地图最右边界来决定进入下一关的。

"""

import arcade
import os
import time

SPRITE_SCALING = 0.5

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Python平铺地图多关卡示例_by lixingqiu"
SPRITE_PIXEL_SIZE = 128
GRID_PIXEL_SIZE = (SPRITE_PIXEL_SIZE * SPRITE_SCALING)

# 视口边距
VIEWPORT_MARGIN_TOP = 60
VIEWPORT_MARGIN_BOTTOM = 60
VIEWPORT_RIGHT_MARGIN = 270
VIEWPORT_LEFT_MARGIN = 270

# Physics
MOVEMENT_SPEED = 5
JUMP_SPEED = 23
GRAVITY = 1.1


class MyGame(arcade.Window):
    """ 继承自窗口的游戏类. """

    def __init__(self):
        """
        初始化方法
        """
        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
        
        # 定义角色列表
        self.wall_list = None
        self.player_list = None
        self.coin_list = None

        # 定义玩家相关变量
        self.score = 0
        self.player_sprite = None

        self.physics_engine = None
        self.view_left = 0
        self.view_bottom = 0
        self.game_over = False
        self.last_time = None       # 用来算fps的上次时间变量
        self.frame_count = 0        # 帧计数器
        self.fps_message = None     # fps字符串

        self.level = 1
        self.max_level = 2

    def setup(self):
        """ 设置与初始化变量的值. """

        # 角色列表初始化
        self.player_list = arcade.SpriteList()
        self.coin_list = arcade.SpriteList()

        # 玩家操作的角色实例化,这里是一只昆虫
        self.player_sprite = arcade.Sprite("images/lixingqiu.png", SPRITE_SCALING)

        # 给昆虫设定坐标
        self.player_sprite.center_x = 64
        self.player_sprite.center_y = 64
        self.player_list.append(self.player_sprite)

        self.load_level(self.level) # 加载第一关

        self.game_over = False

    def load_level(self, level):
        # 读取第一关的地图
        my_map = arcade.read_tiled_map(f"level_{level}.tmx", SPRITE_SCALING)

        # 其它情况,如有背景颜色属性
        if my_map.backgroundcolor:
            arcade.set_background_color(my_map.backgroundcolor)

        # 设置视口以便移动这个矩形
        self.view_left = 0
        self.view_bottom = 0

    def on_draw(self):
        """
        渲染屏幕
        """

        self.frame_count += 1      # 帧计数器

        # 开始渲染屏幕
        arcade.start_render()

        # 画所有的角色
        self.player_list.draw()
        self.wall_list.draw()
        self.coin_list.draw()


    def on_key_press(self, key, modifiers):
        """
        当按键时调用此方法
        """
        if key == arcade.key.UP:
            if self.physics_engine.can_jump():
                self.player_sprite.change_y = JUMP_SPEED
        elif key == arcade.key.LEFT:
            self.player_sprite.change_x = -MOVEMENT_SPEED
        elif key == arcade.key.RIGHT:
            self.player_sprite.change_x = MOVEMENT_SPEED

    def on_key_release(self, key, modifiers):
        """
        当松开键时调用此方法
        """
        if key == arcade.key.LEFT or key == arcade.key.RIGHT:
            self.player_sprite.change_x = 0

    def update(self, delta_time):
        """ 移动与游戏的逻辑 """


def main():
    window = MyGame()
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, python | Arcade街机平铺地图多关卡示例已关闭评论

Arcade街机模块中tmx地图使用方法示例

"""
本程序加载一个tmx地图。
tmx地图文件是一个xml文件,记录了地图的属性,详细地描述了地图的情况。里面主要的标签有map标签,tileset标签,layer标签和data标签。
map标签记录地图整个属性,如宽度,高度,渲染顺序,图块宽高,
tileset标签记录图块信息,主要是图块集的来源
layer标签记录图层信息,图层有id,有名字,有宽度,有高度。有些图层用来做地面或平台,有些图层上面放金币而不做为平台的一部分。
data标签记录图块的二维信息。和csv记录的信息相似。
以下是一个tmx文件示例://后面内容不是的。

<?xml version="1.0" encoding="UTF-8"?>
<map version="1.2" tiledversion="1.2.2" orientation="orthogonal" renderorder="right-down" width="20" height="7" maker="lixingqiu" tilewidth="64" tileheight="64" infinite="0" nextlayerid="3" nextobjectid="1">
 <tileset firstgid="1" source="platformPack_tilesheet.tsx"/>
 <layer id="1" name="平台" width="20" height="7">   //图层1是平台,就是角色跳来跳去的那个地面,这些地面由图块组成,下面的data就是描述它们的类型和位置的。
  <data encoding="csv">
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
0,0,0,85,85,85,85,85,85,0,0,0,0,0,0,0,0,0,0,0,
0,0,85,85,85,88,0,0,0,0,0,0,0,0,0,1,1,1,0,0,
85,85,85,85,85,0,0,1,1,0,0,0,0,0,1,4,4,4,1,0,
0,0,0,0,0,0,1,4,4,1,76,0,0,1,1,4,4,4,1,1,
1,1,1,1,1,1,4,4,1,1,1,1,1,1,1,4,4,4,1,1,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
</data>
 </layer>
 <layer id="2" name="coin" width="20" height="7">   //图层2是金币道具层,角色接收金币,这些金币放在哪?这里就是描述它们by lixingqiu。
  <data encoding="csv">
49,49,49,49,49,49,49,49,49,49,0,0,0,0,0,0,0,0,0,0,
0,49,49,49,49,49,49,49,49,49,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,49,49,49,49,49,49,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
 </layer>
</map>


"""

import arcade
import os
import time

SPRITE_SCALING = 0.5

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Arcade街机模块中tmx地图使用方法示例"
SPRITE_PIXEL_SIZE = 128
GRID_PIXEL_SIZE = (SPRITE_PIXEL_SIZE * SPRITE_SCALING)

# 视口的左右上下
VIEWPORT_MARGIN_TOP = 60
VIEWPORT_MARGIN_BOTTOM = 60
VIEWPORT_RIGHT_MARGIN = 270
VIEWPORT_LEFT_MARGIN = 270

# 物理参数
MOVEMENT_SPEED = 5
JUMP_SPEED = 23
GRAVITY = 1.1


class MyGame(arcade.Window):
    """ Main application class. """

    def __init__(self):
        """
        Initializer
        """
        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)      

        # 定义角色列表
        self.wall_list = None
        self.player_list = None
        self.coin_list = None

        # 定义玩家变量
        self.score = 0
        self.player_sprite = None

        self.physics_engine = None
        self.view_left = 0
        self.view_bottom = 0
        self.game_over = False
        self.last_time = None
        self.frame_count = 0
        self.fps_message = None

    def setup(self):
        """ Set up the game and initialize the variables. """

        # 角色列表实例化
        self.player_list = arcade.SpriteList()
        self.coin_list = arcade.SpriteList()

        # 玩家实例化
        self.player_sprite = arcade.Sprite("images/character.png", SPRITE_SCALING)

        # 玩家起始坐标
        self.player_sprite.center_x = 64
        self.player_sprite.center_y = 270
        self.player_list.append(self.player_sprite)

        platforms_layer_name = 'Platforms'   # 平台层的名称
        coins_layer_name = 'Coins'           # 金币层的名称
        map_name = "map.tmx"

        # 加载地图到内存
        my_map = arcade.read_tiled_map(map_name, SPRITE_SCALING)

        # 墙也就是平台阵列
        map_array = my_map.layers_int_data[platforms_layer_name]

        # 地图宽度
        self.end_of_map = len(map_array[0]) * GRID_PIXEL_SIZE

        # 根据地图和图层产生墙列表
        self.wall_list = arcade.generate_sprites(my_map, platforms_layer_name, SPRITE_SCALING)

        # 根据地图和图层产生金币列表
        self.coin_list = arcade.generate_sprites(my_map, coins_layer_name, SPRITE_SCALING)

        # 如果有背景颜色属性则设置背景颜色
        if my_map.backgroundcolor:
            arcade.set_background_color(my_map.backgroundcolor)

        #设定平台型的物理引擎
        self.physics_engine = arcade.PhysicsEnginePlatformer(self.player_sprite,
                                                             self.wall_list,
                                                             gravity_constant=GRAVITY)


        # 设定视口初始边界
        self.view_left = 0
        self.view_bottom = 0

        self.game_over = False

    def on_draw(self):
        """
        Render the screen.
        """

        self.frame_count += 1

        # 此命令要在所有绘画命令之前执行
        arcade.start_render()

        # 画所有的角色
        self.player_list.draw()
        self.wall_list.draw()
        self.coin_list.draw()

        if self.last_time and self.frame_count % 60 == 0:   # 约1秒显示一次fps
            fps = 1.0 / (time.time() - self.last_time) * 60
            self.fps_message = f"FPS: {fps:5.0f}"

        if self.fps_message:
            arcade.draw_text(self.fps_message, self.view_left + 10, self.view_bottom + 40, arcade.color.BLACK, 14)

        if self.frame_count % 60 == 0:
            self.last_time = time.time()

        # 在左下角写上距离
        distance = self.player_sprite.right
        output = f"Distance: {distance}"
        arcade.draw_text(output, self.view_left + 10, self.view_bottom + 20, arcade.color.BLACK, 14)

        if self.game_over:
            arcade.draw_text("Game Over", self.view_left + 200, self.view_bottom + 200, arcade.color.BLACK, 30)

    def on_key_press(self, key, modifiers):
        """
        当按键时调用此方法
        """
        if key == arcade.key.UP:
            if self.physics_engine.can_jump():
                self.player_sprite.change_y = JUMP_SPEED
        elif key == arcade.key.LEFT:
            self.player_sprite.change_x = -MOVEMENT_SPEED
        elif key == arcade.key.RIGHT:
            self.player_sprite.change_x = MOVEMENT_SPEED

    def on_key_release(self, key, modifiers):
        """
        当松开键时调用此方法
        """
        if key == arcade.key.LEFT or key == arcade.key.RIGHT:
            self.player_sprite.change_x = 0

    def update(self, delta_time):
        """ 移动角色与游戏逻辑 """

        if self.player_sprite.right >= self.end_of_map:
            self.game_over = True

        # 游戏没结束时调用物理引擎的更新方法
        if not self.game_over:
            self.physics_engine.update()

        coins_hit = arcade.check_for_collision_with_list(self.player_sprite, self.coin_list)
        for coin in coins_hit:
            coin.kill()
            self.score += 1

        # --- Manage Scrolling ---

        # Track if we need to change the view port

        changed = False

        # Scroll left
        left_bndry = self.view_left + VIEWPORT_LEFT_MARGIN
        if self.player_sprite.left < left_bndry:
            self.view_left -= left_bndry - self.player_sprite.left
            changed = True

        # Scroll right
        right_bndry = self.view_left + SCREEN_WIDTH - VIEWPORT_RIGHT_MARGIN
        if self.player_sprite.right > right_bndry:
            self.view_left += self.player_sprite.right - right_bndry
            changed = True

        # Scroll up
        top_bndry = self.view_bottom + SCREEN_HEIGHT - VIEWPORT_MARGIN_TOP
        if self.player_sprite.top > top_bndry:
            self.view_bottom += self.player_sprite.top - top_bndry
            changed = True

        # Scroll down
        bottom_bndry = self.view_bottom + VIEWPORT_MARGIN_BOTTOM
        if self.player_sprite.bottom < bottom_bndry:
            self.view_bottom -= bottom_bndry - self.player_sprite.bottom
            changed = True

        # If we need to scroll, go ahead and do it.
        if changed:
            self.view_left = int(self.view_left)
            self.view_bottom = int(self.view_bottom)
            arcade.set_viewport(self.view_left,
                                SCREEN_WIDTH + self.view_left,
                                self.view_bottom,
                                SCREEN_HEIGHT + self.view_bottom)


def main():
    window = MyGame()
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()

发表在 arcade | Arcade街机模块中tmx地图使用方法示例已关闭评论

Arcade街机多房间关卡演示例

以下是部分代码预览:

"""
Arcade街机多房间关卡演示例
"""

import arcade
import os

SPRITE_SCALING = 0.5
SPRITE_NATIVE_SIZE = 128
SPRITE_SIZE = int(SPRITE_NATIVE_SIZE * SPRITE_SCALING)

SCREEN_WIDTH = SPRITE_SIZE * 14
SCREEN_HEIGHT = SPRITE_SIZE * 10
SCREEN_TITLE = "Arcade街机多房间关卡演示例"

MOVEMENT_SPEED = 5

class Room:
    """
    房间的父类,只是设定了墙列表和背景属性
    """
    def __init__(self):
        # 定义墙列表
        self.wall_list = None

        # 定义背景属性
        self.background = None


def setup_room_1():
    """
    创建房间一
    """
    room = Room()

    """ 给房间的wall_list赋值. """
    # Sprite lists
    room.wall_list = arcade.SpriteList()

    wall = arcade.Sprite("images/boxCrate_double.png", SPRITE_SCALING)
    wall.left = 7 * SPRITE_SIZE
    wall.bottom = 5 * SPRITE_SIZE
    room.wall_list.append(wall)

    # 可以在房间里加些金币道具等角色

    # 加载此关的背景
    room.background = arcade.load_texture("images/background.jpg")

    return room


def setup_room_2():
    """
    创建房间2
    """
    room = Room()


class MyGame(arcade.Window):
    """ Main application class. """

    def __init__(self, width, height, title):
        """
        Initializer
        """
        super().__init__(width, height, title)

        # 房间的索引号
        self.current_room = 0

        # 定义玩家的一些变量
        self.rooms = None
        self.player_sprite = None
        self.player_list = None
        self.physics_engine = None

    def setup(self):
        """ Set up the game and initialize the variables. """
        # 实例化玩家对象
        self.player_sprite = arcade.Sprite("images/character.png", SPRITE_SCALING)
        self.player_sprite.center_x = 100
        self.player_sprite.center_y = 100
        self.player_list = arcade.SpriteList()
        self.player_list.append(self.player_sprite)

        # 房间列表
        self.rooms = []

        # 设置房间.
        room = setup_room_1()
        self.rooms.append(room)


    def on_draw(self):
        """
        渲染房间
        """


def main():
    """ Main method """
    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()

 

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, python | Arcade街机多房间关卡演示例已关闭评论

双人游戏Arcade街机模块让角色上下斜坡示例

以下是部分代码预览:

"""
双人游戏Arcade街机模块让角色上下斜坡示例。
本程序加载csv地图,根据数字映射加载相应的图块,生成地图。
 
"""
import arcade
import os

SPRITE_SCALING = 0.5

SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
SCREEN_TITLE = "双人游戏让角色上下斜坡示例:lixingqiu译"
SPRITE_PIXEL_SIZE = 128
GRID_PIXEL_SIZE = (SPRITE_PIXEL_SIZE * SPRITE_SCALING)

# 视口边距
VIEWPORT_MARGIN = 40
RIGHT_MARGIN = 150

# 物理参数
MOVEMENT_SPEED = 5
JUMP_SPEED = 14
GRAVITY = 0.5


def get_map():
    """加载以逗号隔开的csv地图,它其实只是一个地图块的二维映射"""
    map_file = open("map_with_ramps_2.csv")
    map_array = []
    for line in map_file:
        line = line.strip()
        map_row = line.split(",")
        for index, item in enumerate(map_row):
            map_row[index] = int(item)
        map_array.append(map_row)
    return map_array


class MyGame(arcade.Window):
    """ 主应用程序类,继承自Arcade的窗口类. """

    def __init__(self, width, height, title):
        """
        初始化方法,参数为宽度,高度,标题
        """

        super().__init__(width, height, title)

        # 设置工作目录
        file_path = os.path.dirname(os.path.abspath(__file__))
        os.chdir(file_path)

        # 角色列表定义
        self.all_sprites_list = None
        self.coin_list = None
        self.player_list = None

        # 玩家定义
        self.player_sprite = None
        self.wall_list = None
        self.physics_engine = None
        self.physics_engine2 = None
        self.view_left = 0
        self.view_bottom = 0
        self.game_over = False

    def start_new_game(self):
        """ Set up the game and initialize the variables. """

        # 实例化角色列表
        self.all_sprites_list = arcade.SpriteList()
        self.wall_list = arcade.SpriteList()
        self.player_list = arcade.SpriteList()

        # 实例化玩家1
        self.player_sprite = arcade.Sprite("images/character.png",
                                           SPRITE_SCALING)
        self.player_sprite.center_x = 64
        self.player_sprite.center_y = 270
        self.player_list.append(self.player_sprite)
        self.all_sprites_list.append(self.player_sprite)

        
        # 实例化玩家2
        self.player_sprite2 = arcade.Sprite("images/character.png",
                                           SPRITE_SCALING)
        self.player_sprite2.center_x = 128
        self.player_sprite2.center_y = 270
        self.player_list.append(self.player_sprite2)
        self.all_sprites_list.append(self.player_sprite2)
        

        map_array = get_map()

        # 设置背景颜色为亚马逊深绿色
        arcade.set_background_color(arcade.color.AMAZON)

        # 设置初始的视口边界
        # 这些值就是我们要滚到的地方
        self.view_left = 0
        self.view_bottom = 0

        self.game_over = False

    def on_draw(self):
        """
        Render the screen.
        """

        # 在绘画之前此渲染命令要先执行
        arcade.start_render()

        # 画所有的角色
        self.wall_list.draw()
        self.player_list.draw()


    def on_key_press(self, key, modifiers):
        """
        按任意键时调用此方法
        """

    def on_key_release(self, key, modifiers):
        """
        松任意键时调用此方法.
        """
        if key == arcade.key.LEFT or key == arcade.key.RIGHT:
            self.player_sprite.change_x = 0
        if key == arcade.key.A or key == arcade.key.D:
            self.player_sprite2.change_x = 0

    def update(self, delta_time):
        """ Movement and game logic """

        if self.player_sprite.right >= self.end_of_map: # 玩家跳出地图总宽度游戏结束
            self.game_over = True
            
        if self.player_sprite2.right >= self.end_of_map: # 玩家跳出地图总宽度游戏结束
            self.game_over = True


        # 所有角色更新
        if not self.game_over:
            self.physics_engine.update()
            self.physics_engine2.update()



def main():
    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
    window.start_new_game()
    arcade.run()


if __name__ == "__main__":
    main()

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, python | 双人游戏Arcade街机模块让角色上下斜坡示例已关闭评论

Arcade触发器例子角色自定义属性演示

"""
Arcade触发器例子角色自定义属性演示,还展示了any和all函数的用法。
操作方法:用鼠标指针操作小人,去碰撞金币,它们就会亮起来。
然后碰右下角的道具,它会把点亮的金币删除。译:lixingqiu
本程序需要Arcade模块运行,它是制作街机游戏的一个Python库。
any函数:可迭代序列中有一个数据用bool运算的结果为真,即为真。
all函数:可迭代序列中有一个数据用bool运算的结果为假,则为假,全部为真,则为真,要不怎么叫all呢。
>>> help(any)
Help on built-in function any in module builtins: 内置模块中的内置函数

any(iterable, /)
    Return True if bool(x) is True for any x in the iterable.可迭代序列中有一个bool运算为真则返回真
    
    If the iterable is empty, return False.如果可迭代序列是空的,返回假

>>> help(all)
Help on built-in function all in module builtins:

all(iterable, /)                            可迭代序列中所有bool运算为真才返回真
    Return True if bool(x) is True for all values x in the iterable.
    
    If the iterable is empty, return True.如果可迭代序列是空的,返回真

>>> 


"""

import arcade
import os

# 常量定义
SPRITE_SCALING_PLAYER = 0.5

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Arcade触发器例子角色自定义属性演示,改编:李兴球"


class MyGame(arcade.Window):
    """ Our custom Window Class"""

    def __init__(self):
        """ Initializer """
        # 调用父类的初始化方法新建一个窗口
        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
 
        # 角色列表定义
        self.player_list = None
        self.coin_list = None

        # 玩家角色定义
        self.player_sprite = None

        # 道具角色定义(触发器)
        self.trigger_sprite = None

        # 不显示鼠标指针
        self.set_mouse_visible(False)

        arcade.set_background_color(arcade.color.AMAZON)

    def setup(self):
        """ 设置游戏,初始化变量"""

        # 实例化角色列表
        self.player_list = arcade.SpriteList()
        self.coin_list = arcade.SpriteList()

        # 实例化角色
        self.player_sprite = arcade.Sprite("images/character.png", SPRITE_SCALING_PLAYER)
        self.player_sprite.center_x = 50         # 角色x坐标
        self.player_sprite.center_y = 150        # 角色的y坐标
        self.player_list.append(self.player_sprite)

        # 实例化一些金币
        for x in range(100, 800, 100):
            coin = arcade.Sprite("images/coin_01.png", scale=0.3, center_x=x, center_y=400)
            coin.intensity = 'dim'           # 这是增加的一个属性
            coin.alpha = 64                  # 透明度
            self.coin_list.append(coin)

        # 创建一个触发器
        self.trigger_sprite = arcade.Sprite("images/bumper.png", scale=0.5, center_x=750, center_y=50)

    def on_draw(self):
        """ Draw everything """
        arcade.start_render()
        self.coin_list.draw()
        self.trigger_sprite.draw()
        self.player_list.draw()

        # Put the instructions on the screen.
        instructions1 = "去碰金币,点亮它吧."
        arcade.draw_text(instructions1, 10, 90, arcade.color.WHITE, 14,font_name='simhei')
        instructions2 = "去碰右下角的道具把亮着的金币销毁吧."
        arcade.draw_text(instructions2, 10, 70, arcade.color.WHITE, 14,font_name='simhei' )

        # Query the property on the coins and show results.
        coins_are_bright = [coin.intensity == 'bright' for coin in self.coin_list]
        output_any = f"有金币被点亮了吗? : {any(coins_are_bright)}"
        arcade.draw_text(output_any, 10, 40, arcade.color.WHITE, 14,font_name='simhei')
        output_all = f"所有金币都被点亮了? : {all(coins_are_bright)}"
        arcade.draw_text(output_all, 10, 20, arcade.color.WHITE, 14,font_name='simhei')

    def on_mouse_motion(self, x, y, dx, dy):
        """ 处理鼠标移动 """

        # 把玩家的坐标放到鼠标指针的坐标
        self.player_sprite.center_x = x
        self.player_sprite.center_y = y

    def update(self, delta_time):
        """ 移动和游戏逻辑 """

        # 更新所有的金币
        self.coin_list.update()

        # 玩家在on_mouse_motion方法中,坐标已经实时更新

        # 创建所碰到的金币列表
        coins_hit_list = arcade.check_for_collision_with_list(self.player_sprite, self.coin_list)

        # 遍历所碰到的金币,把它们点亮
        for coin in coins_hit_list:
            coin.intensity = 'bright'
            coin.alpha = 255

        hit_trigger = arcade.check_for_collision(self.player_sprite, self.trigger_sprite)
        if hit_trigger:
            # 返回亮了的金币列表
            intense_sprites = [sprite for sprite in self.coin_list if sprite.intensity == 'bright']
            for coin in intense_sprites:
                coin.kill()


def main():
    """ Main method """
    window = MyGame()
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()

发表在 arcade | Arcade触发器例子角色自定义属性演示已关闭评论

带上下左右和斜移动平台演示,lixingqiu译

"""
带上下左右和斜移动平台演示。
加载一张csv地图,它是用Tiled程序制作的。
本程序需要Arcade街机游戏模块支持,目前最新版本是2.00b4,(2019/2/28)
可在命令提示符下用户 pip install arcade==2.0.0b4安装,安装后在IDLE中用import arcade
如果提示缺少ffmpeg,则用pip继续安装它即可。以下代码来自官网,注释翻译与改编为lixingqiu
"""
import arcade
import os

SPRITE_SCALING = 0.5

SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 600
SCREEN_TITLE = "带上下左右和斜移动平台演示,lixingqiu译"
SPRITE_PIXEL_SIZE = 128
GRID_PIXEL_SIZE = (SPRITE_PIXEL_SIZE * SPRITE_SCALING)

# 视口边距
VIEWPORT_MARGIN = SPRITE_PIXEL_SIZE * SPRITE_SCALING
RIGHT_MARGIN = 4 * SPRITE_PIXEL_SIZE * SPRITE_SCALING

# 物理常数设定
MOVEMENT_SPEED = 10 * SPRITE_SCALING
JUMP_SPEED = 28 * SPRITE_SCALING
GRAVITY = .9 * SPRITE_SCALING


def get_map():
    """加载逗号隔开的csv地图,返回二维数字表"""
    map_file = open("map.csv")
    map_array = []
    for line in map_file:
        line = line.strip()
        map_row = line.split(",")
        for index, item in enumerate(map_row):
            map_row[index] = int(item)
        map_array.append(map_row)
    return map_array


class MyGame(arcade.Window):
    """ 主要应用程序类,继承自窗口类 """

    def __init__(self, width, height, title):
        """
        初始化方法,这里定义了一些变量。
        """

        super().__init__(width, height, title) 

        # 定义一些列表
        self.all_sprites_list = None
        self.all_wall_list = None
        self.static_wall_list = None
        self.moving_wall_list = None
        self.player_list = None
        self.coin_list = None

        #  给玩家角色定义一些变量
        self.player_sprite = None
        self.physics_engine = None
        self.view_left = 0
        self.view_bottom = 0
        self.game_over = False

    def setup(self):
        """ 设置游戏,实例化一些变量. """

        # 角色列表实例化
        self.all_sprites_list = arcade.SpriteList()
        self.all_wall_list = arcade.SpriteList()
        self.static_wall_list = arcade.SpriteList()
        self.moving_wall_list = arcade.SpriteList()
        self.player_list = arcade.SpriteList()

        # 实例化玩家角色
        self.player_sprite = arcade.Sprite("images/character.png", SPRITE_SCALING)
        self.player_sprite.center_x = 2 * GRID_PIXEL_SIZE
        self.player_sprite.center_y = 3 * GRID_PIXEL_SIZE
        self.player_list.append(self.player_sprite)

        map_array = get_map()

        # 地图像素长度
        self.end_of_map = len(map_array[0]) * GRID_PIXEL_SIZE
        # 根据csv里的数字决定实例化的墙块的类型
        for row_index, row in enumerate(map_array):
            for column_index, item in enumerate(row):

                if item == -1:
                    continue
                elif item == 0:
                    wall = arcade.Sprite("images/boxCrate_double.png", SPRITE_SCALING)
                elif item == 1:
                    wall = arcade.Sprite("images/grassLeft.png", SPRITE_SCALING)
                elif item == 2:
                    wall = arcade.Sprite("images/grassMid.png", SPRITE_SCALING)
                elif item == 3:
                    wall = arcade.Sprite("images/grassRight.png", SPRITE_SCALING)

                wall.left = column_index * GRID_PIXEL_SIZE
                wall.top = (7 - row_index) * GRID_PIXEL_SIZE
                self.all_sprites_list.append(wall)
                self.all_wall_list.append(wall)
                self.static_wall_list.append(wall)

        # 创建左右移动的平台
        wall = arcade.Sprite("images/grassMid.png", SPRITE_SCALING)
        wall.center_y = 3 * GRID_PIXEL_SIZE
        wall.center_x = 3 * GRID_PIXEL_SIZE
        wall.boundary_left = 2 * GRID_PIXEL_SIZE
        wall.boundary_right = 5 * GRID_PIXEL_SIZE
        wall.change_x = 2 * SPRITE_SCALING

        self.all_sprites_list.append(wall)
        self.all_wall_list.append(wall)
        self.moving_wall_list.append(wall)

        # C建左右移动的平台
        wall = arcade.Sprite("images/grassMid.png", SPRITE_SCALING)
        wall.center_y = 3 * GRID_PIXEL_SIZE
        wall.center_x = 7 * GRID_PIXEL_SIZE
        wall.boundary_left = 5 * GRID_PIXEL_SIZE
        wall.boundary_right = 9 * GRID_PIXEL_SIZE
        wall.change_x = -2 * SPRITE_SCALING

        self.all_sprites_list.append(wall)
        self.all_wall_list.append(wall)
        self.moving_wall_list.append(wall)

        # 建上下移动的平台
        wall = arcade.Sprite("images/grassMid.png", SPRITE_SCALING)
        wall.center_y = 5 * GRID_PIXEL_SIZE
        wall.center_x = 5 * GRID_PIXEL_SIZE
        wall.boundary_top = 8 * GRID_PIXEL_SIZE
        wall.boundary_bottom = 4 * GRID_PIXEL_SIZE
        wall.change_y = 2 * SPRITE_SCALING

        self.all_sprites_list.append(wall)
        self.all_wall_list.append(wall)
        self.moving_wall_list.append(wall)

        # 建斜向移动的平台
        wall = arcade.Sprite("images/grassMid.png", SPRITE_SCALING)
        wall.center_y = 5 * GRID_PIXEL_SIZE
        wall.center_x = 8 * GRID_PIXEL_SIZE
        wall.boundary_left = 7 * GRID_PIXEL_SIZE
        wall.boundary_right = 9 * GRID_PIXEL_SIZE

        wall.boundary_top = 8 * GRID_PIXEL_SIZE
        wall.boundary_bottom = 4 * GRID_PIXEL_SIZE
        wall.change_x = 2 * SPRITE_SCALING
        wall.change_y = 2 * SPRITE_SCALING

        self.all_sprites_list.append(wall)
        self.all_wall_list.append(wall)
        self.moving_wall_list.append(wall)

        # 加载平台型的物理引擎
        self.physics_engine = \
            arcade.PhysicsEnginePlatformer(self.player_sprite,
                                           self.all_wall_list,
                                           gravity_constant=GRAVITY)

        # 设置背景颜色为亚马逊绿
        arcade.set_background_color(arcade.color.AMAZON)

        # 设置视区初始值 
        self.view_left = 0
        self.view_bottom = 0

        self.game_over = False

    def on_draw(self):
        """
        每帧重画屏幕
        """

        # 重画所有对象之前要先调用下面的命令
        arcade.start_render()

        # 画所有角色
        self.static_wall_list.draw()
        self.moving_wall_list.draw()
        self.player_list.draw()

        # Put the text on the screen.
        # Adjust the text position based on the viewport so that we don't
        # scroll the text too.
        # 根据视区左下角坐标放置得分文本
        distance = self.player_sprite.right
        output = f"Distance: {distance}"
        arcade.draw_text(output, self.view_left + 10, self.view_bottom + 20,
                         arcade.color.WHITE, 14)

        if self.game_over:
            output = "Game Over"
            arcade.draw_text(output, self.view_left + 200,
                             self.view_bottom + 200,
                             arcade.color.WHITE, 30)

    def on_key_press(self, key, modifiers):
        """
        当键按下时调用此方法
        """
        if key == arcade.key.UP:
            if self.physics_engine.can_jump():
                self.player_sprite.change_y = JUMP_SPEED
        elif key == arcade.key.LEFT:
            self.player_sprite.change_x = -MOVEMENT_SPEED
        elif key == arcade.key.RIGHT:
            self.player_sprite.change_x = MOVEMENT_SPEED

    def on_key_release(self, key, modifiers):
        """
        当键松开时调用此方法
        """
        if key == arcade.key.LEFT or key == arcade.key.RIGHT:
            self.player_sprite.change_x = 0

    def update(self, delta_time):
        """ 移动角色们与游戏逻辑 """

        if self.player_sprite.right >= self.end_of_map:
            self.game_over = True

        # 更新所有角色
        if not self.game_over:
            self.physics_engine.update()
 

        changed = False

        # 视口左滚动 self.view_left是视口最左x坐标
        left_boundary = self.view_left + VIEWPORT_MARGIN
        if self.player_sprite.left < left_boundary:
            self.view_left -= left_boundary - self.player_sprite.left # 视口往左移,弥补差
            changed = True

        # Scroll right
        right_boundary = self.view_left + SCREEN_WIDTH - RIGHT_MARGIN
        if self.player_sprite.right > right_boundary:
            self.view_left += self.player_sprite.right - right_boundary
            changed = True

        # Scroll up
        top_boundary = self.view_bottom + SCREEN_HEIGHT - VIEWPORT_MARGIN
        if self.player_sprite.top > top_boundary:
            self.view_bottom += self.player_sprite.top - top_boundary
            changed = True

        # Scroll down
        bottom_boundary = self.view_bottom + VIEWPORT_MARGIN
        if self.player_sprite.bottom < bottom_boundary:
            self.view_bottom -= bottom_boundary - self.player_sprite.bottom
            changed = True

        # 如果改变了重新设置视口
        if changed:
            arcade.set_viewport(self.view_left,
                                SCREEN_WIDTH + self.view_left,
                                self.view_bottom,
                                SCREEN_HEIGHT + self.view_bottom)


def main():
    """ Main method """
    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()

发表在 arcade | 带上下左右和斜移动平台演示,lixingqiu译已关闭评论

朝向式的移动角色示例,坦克那样移动示例

以下是部分代码预览:

"""
朝向式的移动角色示例,本程序按左右键改变角色方向,按上下键移动角色,并且图片同时会旋转。
它让角色像Python的海龟画图里的海龟一样移动。注释翻译:李兴球
"""
import arcade
import os
import math

SPRITE_SCALING = 0.5

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "朝向式的移动角色示例,坦克那样移动示例"

MOVEMENT_SPEED = 5
ANGLE_SPEED = 5


class Player(arcade.Sprite):
    """ 玩家类继承自角色类 """

    def __init__(self, image, scale):
        """ 初始化玩家 """

        # 调用玩家父类方法
        super().__init__(image, scale)

        # 速度变量
        self.speed = 0

class MyGame(arcade.Window):
    """
    主要的游戏类
    """

    def __init__(self, width, height, title):
        """
        Initializer        """

        # 调用父类初始化方法
        super().__init__(width, height, title)
        
        # 玩家列表
        self.player_list = None

        # 玩家角色变量的定义
        self.player_sprite = None

        # 设置背景为黑色
        arcade.set_background_color(arcade.color.BLACK)

    def setup(self):
        """ 设置游戏参数 """

        # Sprite lists
        self.player_list = arcade.SpriteList()

        # Set up the player
        self.player_sprite = Player("images/playerShip1_orange.png", SPRITE_SCALING)
        self.player_sprite.center_x = SCREEN_WIDTH / 2
        self.player_sprite.center_y = SCREEN_HEIGHT / 2
        self.player_list.append(self.player_sprite)


def main():
    """ Main method """
    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()

 

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, python | 朝向式的移动角色示例,坦克那样移动示例已关闭评论

用三角函数实现朝向玩家方向移动

以下是部分代码预览:

"""
用三角函数实现朝向玩家方向移动
来自arcade官方网站改编。本程序实现金币角色自动朝向玩家移动。
"""

import random
import arcade
import math
import os

# --- Constants ---
SPRITE_SCALING_PLAYER = 0.5
SPRITE_SCALING_COIN = 0.2
COIN_COUNT = 50
COIN_SPEED = 0.5

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "用三角函数实现朝向玩家方向移动_注释翻译 :李兴球"

SPRITE_SPEED = 0.5

class Coin(arcade.Sprite):
    """
    Coin类是角色类的子弹,只是给它增加了一个方法而已
    """

    def follow_sprite(self, player_sprite):
        """
        向着玩家角色的方向移动
        """

        self.center_x += self.change_x  # 在水平方向上移动change_x
        self.center_y += self.change_y  # 在垂直方向上移动change_y


class MyGame(arcade.Window):
    """ Our custom Window Class"""

    def __init__(self):
        """ Initializer """
        # 调用父类的实始化方法
        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)

        # 设置工作目录 
        file_path = os.path.dirname(os.path.abspath(__file__))
        os.chdir(file_path)

   
    def setup(self):
        """ 设置游戏,实例化变量的值 """

        # 实例化角色列表
        self.player_list = arcade.SpriteList()
        self.coin_list = arcade.SpriteList()

        # 得分初始值为0
        self.score = 0

        # 创建一些金币
        for i in range(COIN_COUNT):

            # 实例化金币
            coin = Coin("images/coin_01.png", SPRITE_SCALING_COIN)

            # 放到随机坐标位置
            coin.center_x = random.randrange(SCREEN_WIDTH)
            coin.center_y = random.randrange(SCREEN_HEIGHT)

            # 增加到金币列表
            self.coin_list.append(coin)

    def on_draw(self):
        """ 重画所有对象"""
        arcade.start_render()
        self.coin_list.draw()
        self.player_list.draw()

        # 显示文本
        output = f"Score: {self.score}"
        arcade.draw_text(output, 10, 20, arcade.color.WHITE, 14)

    def on_mouse_motion(self, x, y, dx, dy):
        """ 鼠标移动事件 """

        #  用鼠标操作玩家
        self.player_sprite.center_x = x
        self.player_sprite.center_y = y

    def update(self, delta_time):
        """ 移动与游戏逻辑 """

        for coin in self.coin_list: # 让每个金币朝向玩家移动
            coin.follow_sprite(self.player_sprite)


def main():
    """ Main method """
    window = MyGame()
    window.setup()
    arcade.run()

if __name__ == "__main__":
    main()

 

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 arcade, python | 用三角函数实现朝向玩家方向移动已关闭评论