Pygame constants.py

一些按键相关,以及一些屏幕处理的常量

# encoding: utf-8
# module pygame.constants
# from D:\Software\AnAconda\lib\site-packages\pygame\constants.cp36-win_amd64.pyd
# by generator 1.145
""" Constants defined by SDL and needed in Pygame. """
# no imports

# Variables with simple values

ACTIVEEVENT = 1

ANYFORMAT = 268435456

ASYNCBLIT = 4

AUDIO_S16 = 32784
AUDIO_S16LSB = 32784
AUDIO_S16MSB = 36880
AUDIO_S16SYS = 32784
AUDIO_S8 = 32776
AUDIO_U16 = 16
AUDIO_U16LSB = 16
AUDIO_U16MSB = 4112
AUDIO_U16SYS = 16
AUDIO_U8 = 8

BIG_ENDIAN = 4321

BLEND_ADD = 1
BLEND_MAX = 5
BLEND_MIN = 4
BLEND_MULT = 3
BLEND_PREMULTIPLIED = 17

BLEND_RGBA_ADD = 6
BLEND_RGBA_MAX = 16
BLEND_RGBA_MIN = 9
BLEND_RGBA_MULT = 8
BLEND_RGBA_SUB = 7

BLEND_RGB_ADD = 1
BLEND_RGB_MAX = 5
BLEND_RGB_MIN = 4
BLEND_RGB_MULT = 3
BLEND_RGB_SUB = 2

BLEND_SUB = 2

BUTTON_X1 = 6
BUTTON_X2 = 7

DOUBLEBUF = 1073741824

FULLSCREEN = -2147483648

GL_ACCELERATED_VISUAL = 15

GL_ACCUM_ALPHA_SIZE = 11

GL_ACCUM_BLUE_SIZE = 10

GL_ACCUM_GREEN_SIZE = 9

GL_ACCUM_RED_SIZE = 8

GL_ALPHA_SIZE = 3

GL_BLUE_SIZE = 2

GL_BUFFER_SIZE = 4

GL_DEPTH_SIZE = 6

GL_DOUBLEBUFFER = 5

GL_GREEN_SIZE = 1

GL_MULTISAMPLEBUFFERS = 13
GL_MULTISAMPLESAMPLES = 14

GL_RED_SIZE = 0

GL_STENCIL_SIZE = 7

GL_STEREO = 12

GL_SWAP_CONTROL = 16

HAT_CENTERED = 0
HAT_DOWN = 4
HAT_LEFT = 8
HAT_LEFTDOWN = 12
HAT_LEFTUP = 9
HAT_RIGHT = 2
HAT_RIGHTDOWN = 6
HAT_RIGHTUP = 3
HAT_UP = 1

HWACCEL = 256
HWPALETTE = 536870912
HWSURFACE = 1

IYUV_OVERLAY = 1448433993

JOYAXISMOTION = 7
JOYBALLMOTION = 8
JOYBUTTONDOWN = 10
JOYBUTTONUP = 11
JOYHATMOTION = 9

KEYDOWN = 2
KEYUP = 3

KMOD_ALT = 768
KMOD_CAPS = 8192
KMOD_CTRL = 192
KMOD_LALT = 256
KMOD_LCTRL = 64
KMOD_LMETA = 1024
KMOD_LSHIFT = 1
KMOD_META = 3072
KMOD_MODE = 16384
KMOD_NONE = 0
KMOD_NUM = 4096
KMOD_RALT = 512
KMOD_RCTRL = 128
KMOD_RMETA = 2048
KMOD_RSHIFT = 2
KMOD_SHIFT = 3

K_0 = 48
K_1 = 49
K_2 = 50
K_3 = 51
K_4 = 52
K_5 = 53
K_6 = 54
K_7 = 55
K_8 = 56
K_9 = 57
K_a = 97
K_AMPERSAND = 38
K_ASTERISK = 42
K_AT = 64
K_b = 98
K_BACKQUOTE = 96
K_BACKSLASH = 92
K_BACKSPACE = 8
K_BREAK = 318
K_c = 99
K_CAPSLOCK = 301
K_CARET = 94
K_CLEAR = 12
K_COLON = 58
K_COMMA = 44
K_d = 100
K_DELETE = 127
K_DOLLAR = 36
K_DOWN = 274
K_e = 101
K_END = 279
K_EQUALS = 61
K_ESCAPE = 27
K_EURO = 321
K_EXCLAIM = 33
K_f = 102
K_F1 = 282
K_F10 = 291
K_F11 = 292
K_F12 = 293
K_F13 = 294
K_F14 = 295
K_F15 = 296
K_F2 = 283
K_F3 = 284
K_F4 = 285
K_F5 = 286
K_F6 = 287
K_F7 = 288
K_F8 = 289
K_F9 = 290
K_FIRST = 0
K_g = 103
K_GREATER = 62
K_h = 104
K_HASH = 35
K_HELP = 315
K_HOME = 278
K_i = 105
K_INSERT = 277
K_j = 106
K_k = 107
K_KP0 = 256
K_KP1 = 257
K_KP2 = 258
K_KP3 = 259
K_KP4 = 260
K_KP5 = 261
K_KP6 = 262
K_KP7 = 263
K_KP8 = 264
K_KP9 = 265

K_KP_DIVIDE = 267
K_KP_ENTER = 271
K_KP_EQUALS = 272
K_KP_MINUS = 269
K_KP_MULTIPLY = 268
K_KP_PERIOD = 266
K_KP_PLUS = 270

K_l = 108
K_LALT = 308
K_LAST = 323
K_LCTRL = 306
K_LEFT = 276
K_LEFTBRACKET = 91
K_LEFTPAREN = 40
K_LESS = 60
K_LMETA = 310
K_LSHIFT = 304
K_LSUPER = 311
K_m = 109
K_MENU = 319
K_MINUS = 45
K_MODE = 313
K_n = 110
K_NUMLOCK = 300
K_o = 111
K_p = 112
K_PAGEDOWN = 281
K_PAGEUP = 280
K_PAUSE = 19
K_PERIOD = 46
K_PLUS = 43
K_POWER = 320
K_PRINT = 316
K_q = 113
K_QUESTION = 63
K_QUOTE = 39
K_QUOTEDBL = 34
K_r = 114
K_RALT = 307
K_RCTRL = 305
K_RETURN = 13
K_RIGHT = 275
K_RIGHTBRACKET = 93
K_RIGHTPAREN = 41
K_RMETA = 309
K_RSHIFT = 303
K_RSUPER = 312
K_s = 115
K_SCROLLOCK = 302
K_SEMICOLON = 59
K_SLASH = 47
K_SPACE = 32
K_SYSREQ = 317
K_t = 116
K_TAB = 9
K_u = 117
K_UNDERSCORE = 95
K_UNKNOWN = 0
K_UP = 273
K_v = 118
K_w = 119
K_x = 120
K_y = 121
K_z = 122

LIL_ENDIAN = 1234

MOUSEBUTTONDOWN = 5
MOUSEBUTTONUP = 6
MOUSEMOTION = 4

NOEVENT = 0
NOFRAME = 32

NUMEVENTS = 32

OPENGL = 2
OPENGLBLIT = 10

PREALLOC = 16777216

QUIT = 12

RESIZABLE = 16

RLEACCEL = 16384
RLEACCELOK = 8192

SCRAP_BMP = 'image/bmp'
SCRAP_CLIPBOARD = 0
SCRAP_PBM = 'image/pbm'
SCRAP_PPM = 'image/ppm'
SCRAP_SELECTION = 1
SCRAP_TEXT = 'text/plain'

SRCALPHA = 65536
SRCCOLORKEY = 4096

SWSURFACE = 0

SYSWMEVENT = 13

TIMER_RESOLUTION = 10

USEREVENT = 24

USEREVENT_DROPFILE = 4096

UYVY_OVERLAY = 1498831189

VIDEOEXPOSE = 17
VIDEORESIZE = 16

YUY2_OVERLAY = 844715353

YV12_OVERLAY = 842094169

YVYU_OVERLAY = 1431918169

# no functions
# no classes
# variables with complex values

__loader__ = None # (!) real value is ''

__spec__ = None # (!) real value is ''


pygame 碰撞检测

碰撞检测 即两个Sprite是否碰撞-重叠之类的(你懂得)
:horse_racing:

github: https://github.com/834930269/Pygame-Learn/tree/master/EatApple

吃苹果游戏:

# MyLibrary.py
from pygame import *
import sys, time, random, math, pygame

def print_text(font,x,y,text,color=(255,255,255)):
    imgText = font.render(text,True,color)
    #req'd when function moved into MyLibrary
    screen = pygame.display.get_surface()
    #移动
    screen.blit(imgText,(x,y))

class MySprite(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.master_image = None
        self.frame = 0
        self.old_frame = -1
        self.frame_width = 1
        self.frame_height = 1
        self.first_frame = 0
        self.last_frame = 0
        self.columns = 1
        self.last_time = 0
        self.row = 1
        self.direction = 0
        self.velocity = Point(0.0,0.0)

    #x property
    def _getx(self): return self.rect.x
    def _setx(self,value): self.rect.x = value
    X = property(_getx,_setx)

    #y property
    def _gety(self): return self.rect.y
    def _sety(self,value): self.rect.y = value
    Y = property(_gety,_sety)

    # position property
    def _getpos(self): return self.rect.topleft
    def _setpos(self,pos):self.rect.topleft = pos
    position = property(_getpos,_setpos)

    # filename 帧图宽度,帧图高度,帧图行,帧图列
    def load(self,filename,width,height,columns,row):
        self.master_image = pygame.image.load(filename).convert_alpha()
        self.frame_width = width
        self.frame_height = height
        self.rect = Rect(0,0,width,height)
        self.columns = columns
        self.row = row
        rect = self.master_image.get_rect()
        self.last_frame = (rect.width // width)*(rect.height // height) - 1

    def update(self,current_time,rate=30):
        if current_time > self.last_time +rate:
            self.frame += 1
            if self.frame > self.last_frame:
                self.frame = self.first_frame
            self.last_frame = current_time

        if self.frame != self.old_frame:
            frame_x = (self.frame % self.columns) * self.frame_width
            #添加了row以后每次计算对row取余即可计算出当前列数
            frame_y = (self.frame // self.columns) % self.row * self.frame_height
            #如果把frame_y置为0,则表示始终都是在位图的第一行
            # 多行的话,可以通过frame_y来解决,但是要注意,y=0则返回
            rect = Rect(frame_x, frame_y, self.frame_width, self.frame_height)
            self.image = self.master_image.subsurface(rect)
            self.old_frame = self.frame

    def __str__(self):
        return str(self.frame) + "," + str(self.first_frame) + \
            "," + str(self.last_frame) + "," + str(self.frame_width) + \
            "," + str(self.frame_height) + "," + str(self.columns) + \
            "," + str(self.rect)

#Point class
class Point(object):
    def __init__(self,x,y):
        self.__x = x
        self.__y = y
    #X property
    def getx(self): return self.__x
    def setx(self, x): self.__x = x
    x = property(getx, setx)

    #Y property
    def gety(self): return self.__y
    def sety(self, y): self.__y = y
    y = property(gety, sety)

    def __str__(self):
        return "{X:" + "{:.0f}".format(self.__x) + \
            ",Y:" + "{:.0f}".format(self.__y) + "}"
#app.py
import itertools, sys, time, random, math, pygame
from pygame import *
from MyLibrary import *

def calc_velocity(direction,vel=1.0):
    velocity = Point(0,0)
    if direction == 0 :#上
        velocity.y = -vel
    elif direction == 2:#右
        velocity.x=vel
    elif direction == 4:#下
        velocity.y=vel
    elif direction == 6:#左
        velocity.x=-vel
    return velocity

pygame.init()
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption("吃苹果")
font = pygame.font.Font(None,36)
timer = pygame.time.Clock()

#创建精灵组
player_group = pygame.sprite.Group()
food_group = pygame.sprite.Group()

#初始化玩家精灵组
player = MySprite()
player.load("farmer walk.png",96,96,8,8)
#初始位置
player.position = 80,80
#初始方向
player.direction = 4
#添加进组
player_group.add(player)

#初始化食物精灵组
for n in range(1,50):
    food = MySprite()
    food.load("food_low.png",35,35,1,1)
    #随机分布
    food.position = random.randint(0,780),random.randint(0,580)
    food_group.add(food)

game_over=False
player_moving = False
player_health = 0

while True:
    timer.tick(30)
    ticks = pygame.time.get_ticks()

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    #获取当前按键
    keys = pygame.key.get_pressed()
    if keys[K_ESCAPE]:
        sys.exit()
    elif keys[K_UP] or keys[K_w]:#上
        player.direction = 0
        player_moving = True
    elif keys[K_RIGHT] or keys[K_d]:#右
        player.direction = 2
        player_moving = True
    elif keys[K_DOWN] or keys[K_s]:#下
        player.direction = 4
        player_moving = True
    elif keys[K_LEFT] or keys[K_a]:#左
        player.direction = 6
        player_moving = True
    else:
        player_moving = False

    if not game_over:
        #根据角色方向不同,使用不同的动画帧
        player.first_frame = player.direction * player.columns
        player.last_frame = player.first_frame + player.columns-1
        if player.frame < player.first_frame:
            player.frame = player.first_frame

        if not player_moving:
            # 当停止按键(即人物停止移动的时候),停止更新动画帧
            player.frame = player.first_frame = player.last_frame
        else:
            player.velocity = calc_velocity(player.direction,1.5)
            player.velocity.x *= 1.5
            player.velocity.y *= 1.5

        #更新玩家精灵组
        player_group.update(ticks, 50)
        # 移动玩家
        if player_moving:
            player.X += player.velocity.x
            player.Y += player.velocity.y
            if player.X < 0:
                player.X = 0
            elif player.X > 700:
                player.X = 700
            if player.Y < 0:
                player.Y = 0
            elif player.Y > 500:
                player.Y = 500

        attacker = None
        #判断是否有碰撞产生
        attacker = pygame.sprite.spritecollideany(player,food_group)
        if attacker!=None:
            #有,增加精度
            if pygame.sprite.collide_circle_ratio(0.65)(player,attacker):
                player_health += 2
                food_group.remove(attacker)
        if player_health > 100:
            player_health = 100
        #更新食物精灵组
        food_group.update(ticks,50)
        if len(food_group)==0:
            game_over = True

    #清屏
    screen.fill((50,50,100))
    # 绘制精灵
    food_group.draw(screen)
    player_group.draw(screen)

    # 绘制玩家血量条
    pygame.draw.rect(screen, (50, 150, 50, 180), Rect(300, 570, player_health * 2, 25))
    pygame.draw.rect(screen, (100, 200, 100, 180), Rect(300, 570, 200, 25), 2)

    if game_over:
        print_text(font, 300, 100, "GAME OVER")

    pygame.display.update()

接下来才是难中之难…如果想要实现人物随场景移动.

估计要自己撸框架了.

大体思路如下:
1:近景(左侧)1/2前景不随人物移动
2:1/2以后景随人物移动
3:远景(右侧)1/2前景不随人物移动
4:景采用大地图形式,造可封装类(障碍物,场景地图,宽度,高度等信息)
5:考虑如何移动场景,数学公式想好,-移动方向,移动速度,景中心…
6:加油!

pygame sprite

自定义Sprite类:
让嗷大喵动起来!

以上图片叫做帧图,背景为空,和二维数组一样的用法.
这个帧图的行为4,列为1.

对网上别人自定义的MySprite类做了修改,使其变成列行同时循环.

学习项目地址: pygame-learn-sprite

class MySprite

class MySprite(pygame.sprite.Sprite):
    def __init__(self,target):
        pygame.sprite.Sprite.__init__(self)
        self.target_surface = target
        self.image = None
        self.master_image = None
        self.rect = None
        self.topleft = 0,0
        self.frame = 0
        self.old_frame = -1
        self.frame_width = 1
        self.frame_height = 1
        self.first_frame = 0
        self.last_frame = 0
        self.columns = 1
        self.last_time = 0
        self.row = 1

    # filename 帧图宽度,帧图高度,帧图行,帧图列
    def load(self,filename,width,height,columns,row):
        self.master_image = pygame.image.load(filename).convert_alpha()
        self.frame_width = width
        self.frame_height = height
        self.rect = 0,0,width,height
        self.columns = columns
        self.row = row
        rect = self.master_image.get_rect()
        self.last_frame = (rect.width // width)*(rect.height // height) - 1

    def update(self,current_time,rate=60):
        if current_time > self.last_time +rate:
            self.frame += 1
            if self.frame > self.last_frame:
                self.frame = self.first_frame
            self.last_frame = current_time

        if self.frame != self.old_frame:
            frame_x = (self.frame % self.columns) * self.frame_width
            #添加了row以后每次计算对row取余即可计算出当前列数
            frame_y = (self.frame // self.columns) % self.row * self.frame_height
            #如果把frame_y置为0,则表示始终都是在位图的第一行
            # 多行的话,可以通过frame_y来解决,但是要注意,y=0则返回
            rect = (frame_x, frame_y, self.frame_width, self.frame_height)
            self.image = self.master_image.subsurface(rect)
            self.old_frame = self.frame

让嗷大喵动起来吧!!

import pygame
from pygame import *

class MySprite(pygame.sprite.Sprite):
    def __init__(self,target):
        pygame.sprite.Sprite.__init__(self)
        self.target_surface = target
        self.image = None
        self.master_image = None
        self.rect = None
        self.topleft = 0,0
        self.frame = 0
        self.old_frame = -1
        self.frame_width = 1
        self.frame_height = 1
        self.first_frame = 0
        self.last_frame = 0
        self.columns = 1
        self.last_time = 0
        self.row = 1

    # filename 帧图宽度,帧图高度,帧图行,帧图列
    def load(self,filename,width,height,columns,row):
        self.master_image = pygame.image.load(filename).convert_alpha()
        self.frame_width = width
        self.frame_height = height
        self.rect = 0,0,width,height
        self.columns = columns
        self.row = row
        rect = self.master_image.get_rect()
        self.last_frame = (rect.width // width)*(rect.height // height) - 1

    def update(self,current_time,rate=60):
        if current_time > self.last_time +rate:
            self.frame += 1
            if self.frame > self.last_frame:
                self.frame = self.first_frame
            self.last_frame = current_time

        if self.frame != self.old_frame:
            frame_x = (self.frame % self.columns) * self.frame_width
            #添加了row以后每次计算对row取余即可计算出当前列数
            frame_y = (self.frame // self.columns) % self.row * self.frame_height
            #如果把frame_y置为0,则表示始终都是在位图的第一行
            # 多行的话,可以通过frame_y来解决,但是要注意,y=0则返回
            rect = (frame_x, frame_y, self.frame_width, self.frame_height)
            self.image = self.master_image.subsurface(rect)
            self.old_frame = self.frame

pygame.init()
screen = pygame.display.set_mode((800,600),0,32)
pygame.display.set_caption("精灵测试")
font = pygame.font.Font(None,18)
framerate = pygame.time.Clock()

cat = MySprite(screen)
cat.load("mdm.png",100,100,4,1)
group = pygame.sprite.Group()
group.add(cat)

while True:
    framerate.tick(100)
    ticks = pygame.time.get_ticks()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
    key = pygame.key.get_pressed()
    if key[pygame.K_ESCAPE]:
        exit()

    screen.fill((0,0,100))

    group.update(ticks)
    group.draw(screen)
    pygame.display.update()