效果演示
基础源码
1.基础设置(tools部分)
这个部分设置马里奥以及游戏中蘑菇等怪的的移动设置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
import os import pygame as pg keybinding = { 'action' :pg.K_s, 'jump' :pg.K_a, 'left' :pg.K_LEFT, 'right' :pg.K_RIGHT, 'down' :pg.K_DOWN } class Control( object ): """Control class for entire project. Contains the game loop, and contains the event_loop which passes events to States as needed. Logic for flipping states is also found here.""" def __init__( self , caption): self .screen = pg.display.get_surface() self .done = False self .clock = pg.time.Clock() self .caption = caption self .fps = 60 self .show_fps = False self .current_time = 0.0 self .keys = pg.key.get_pressed() self .state_dict = {} self .state_name = None self .state = None def setup_states( self , state_dict, start_state): self .state_dict = state_dict self .state_name = start_state self .state = self .state_dict[ self .state_name] def update( self ): self .current_time = pg.time.get_ticks() if self .state.quit: self .done = True elif self .state.done: self .flip_state() self .state.update( self .screen, self .keys, self .current_time) def flip_state( self ): previous, self .state_name = self .state_name, self .state. next persist = self .state.cleanup() self .state = self .state_dict[ self .state_name] self .state.startup( self .current_time, persist) self .state.previous = previous def event_loop( self ): for event in pg.event.get(): if event. type = = pg.QUIT: self .done = True elif event. type = = pg.KEYDOWN: self .keys = pg.key.get_pressed() self .toggle_show_fps(event.key) elif event. type = = pg.KEYUP: self .keys = pg.key.get_pressed() self .state.get_event(event) def toggle_show_fps( self , key): if key = = pg.K_F5: self .show_fps = not self .show_fps if not self .show_fps: pg.display.set_caption( self .caption) def main( self ): """Main loop for entire program""" while not self .done: self .event_loop() self .update() pg.display.update() self .clock.tick( self .fps) if self .show_fps: fps = self .clock.get_fps() with_fps = "{} - {:.2f} FPS" . format ( self .caption, fps) pg.display.set_caption(with_fps) class _State( object ): def __init__( self ): self .start_time = 0.0 self .current_time = 0.0 self .done = False self .quit = False self . next = None self .previous = None self .persist = {} def get_event( self , event): pass def startup( self , current_time, persistant): self .persist = persistant self .start_time = current_time def cleanup( self ): self .done = False return self .persist def update( self , surface, keys, current_time): pass def load_all_gfx(directory, colorkey = ( 255 , 0 , 255 ), accept = ( '.png' , 'jpg' , 'bmp' )): graphics = {} for pic in os.listdir(directory): name, ext = os.path.splitext(pic) if ext.lower() in accept: img = pg.image.load(os.path.join(directory, pic)) if img.get_alpha(): img = img.convert_alpha() else : img = img.convert() img.set_colorkey(colorkey) graphics[name] = img return graphics def load_all_music(directory, accept = ( '.wav' , '.mp3' , '.ogg' , '.mdi' )): songs = {} for song in os.listdir(directory): name,ext = os.path.splitext(song) if ext.lower() in accept: songs[name] = os.path.join(directory, song) return songs def load_all_fonts(directory, accept = ( '.ttf' )): return load_all_music(directory, accept) def load_all_sfx(directory, accept = ( '.wav' , '.mpe' , '.ogg' , '.mdi' )): effects = {} for fx in os.listdir(directory): name, ext = os.path.splitext(fx) if ext.lower() in accept: effects[name] = pg.mixer.Sound(os.path.join(directory, fx)) return effects |
2.设置背景音乐以及场景中的文字(setup部分)
该部分主要设置场景中的背景音乐,以及字体的显示等设置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import os import pygame as pg from . import tools from . import constants as c ORIGINAL_CAPTION = c.ORIGINAL_CAPTION os.environ[ 'SDL_VIDEO_CENTERED' ] = '1' pg.init() pg.event.set_allowed([pg.KEYDOWN, pg.KEYUP, pg.QUIT]) pg.display.set_caption(c.ORIGINAL_CAPTION) SCREEN = pg.display.set_mode(c.SCREEN_SIZE) SCREEN_RECT = SCREEN.get_rect() FONTS = tools.load_all_fonts(os.path.join( "resources" , "fonts" )) MUSIC = tools.load_all_music(os.path.join( "resources" , "music" )) GFX = tools.load_all_gfx(os.path.join( "resources" , "graphics" )) SFX = tools.load_all_sfx(os.path.join( "resources" , "sound" )) |
3.设置游戏规则(load_screen)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
from .. import setup, tools from .. import constants as c from .. import game_sound from ..components import info class LoadScreen(tools._State): def __init__( self ): tools._State.__init__( self ) def startup( self , current_time, persist): self .start_time = current_time self .persist = persist self .game_info = self .persist self . next = self .set_next_state() info_state = self .set_overhead_info_state() self .overhead_info = info.OverheadInfo( self .game_info, info_state) self .sound_manager = game_sound.Sound( self .overhead_info) def set_next_state( self ): """Sets the next state""" return c.LEVEL1 def set_overhead_info_state( self ): """sets the state to send to the overhead info object""" return c.LOAD_SCREEN def update( self , surface, keys, current_time): """Updates the loading screen""" if (current_time - self .start_time) < 2400 : surface.fill(c.BLACK) self .overhead_info.update( self .game_info) self .overhead_info.draw(surface) elif (current_time - self .start_time) < 2600 : surface.fill(c.BLACK) elif (current_time - self .start_time) < 2635 : surface.fill(( 106 , 150 , 252 )) else : self .done = True class GameOver(LoadScreen): """A loading screen with Game Over""" def __init__( self ): super (GameOver, self ).__init__() def set_next_state( self ): """Sets next state""" return c.MAIN_MENU def set_overhead_info_state( self ): """sets the state to send to the overhead info object""" return c.GAME_OVER def update( self , surface, keys, current_time): self .current_time = current_time self .sound_manager.update( self .persist, None ) if ( self .current_time - self .start_time) < 7000 : surface.fill(c.BLACK) self .overhead_info.update( self .game_info) self .overhead_info.draw(surface) elif ( self .current_time - self .start_time) < 7200 : surface.fill(c.BLACK) elif ( self .current_time - self .start_time) < 7235 : surface.fill(( 106 , 150 , 252 )) else : self .done = True class TimeOut(LoadScreen): """Loading Screen with Time Out""" def __init__( self ): super (TimeOut, self ).__init__() def set_next_state( self ): """Sets next state""" if self .persist[c.LIVES] = = 0 : return c.GAME_OVER else : return c.LOAD_SCREEN def set_overhead_info_state( self ): """Sets the state to send to the overhead info object""" return c.TIME_OUT def update( self , surface, keys, current_time): self .current_time = current_time if ( self .current_time - self .start_time) < 2400 : surface.fill(c.BLACK) self .overhead_info.update( self .game_info) self .overhead_info.draw(surface) else : self .done = True |
4.设置游戏内菜单等(main_menu)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
import pygame as pg from .. import setup, tools from .. import constants as c from .. components import info, mario class Menu(tools._State): def __init__( self ): """Initializes the state""" tools._State.__init__( self ) persist = {c.COIN_TOTAL: 0 , c.SCORE: 0 , c.LIVES: 3 , c.TOP_SCORE: 0 , c.CURRENT_TIME: 0.0 , c.LEVEL_STATE: None , c.CAMERA_START_X: 0 , c.MARIO_DEAD: False } self .startup( 0.0 , persist) def startup( self , current_time, persist): """Called every time the game's state becomes this one. Initializes certain values""" self . next = c.LOAD_SCREEN self .persist = persist self .game_info = persist self .overhead_info = info.OverheadInfo( self .game_info, c.MAIN_MENU) self .sprite_sheet = setup.GFX[ 'title_screen' ] self .setup_background() self .setup_mario() self .setup_cursor() def setup_cursor( self ): """Creates the mushroom cursor to select 1 or 2 player game""" self .cursor = pg.sprite.Sprite() dest = ( 220 , 358 ) self .cursor.image, self .cursor.rect = self .get_image( 24 , 160 , 8 , 8 , dest, setup.GFX[ 'item_objects' ]) self .cursor.state = c.PLAYER1 def setup_mario( self ): """Places Mario at the beginning of the level""" self .mario = mario.Mario() self .mario.rect.x = 110 self .mario.rect.bottom = c.GROUND_HEIGHT def setup_background( self ): """Setup the background image to blit""" self .background = setup.GFX[ 'level_1' ] self .background_rect = self .background.get_rect() self .background = pg.transform.scale( self .background, ( int ( self .background_rect.width * c.BACKGROUND_MULTIPLER), int ( self .background_rect.height * c.BACKGROUND_MULTIPLER))) self .viewport = setup.SCREEN.get_rect(bottom = setup.SCREEN_RECT.bottom) self .image_dict = {} self .image_dict[ 'GAME_NAME_BOX' ] = self .get_image( 1 , 60 , 176 , 88 , ( 170 , 100 ), setup.GFX[ 'title_screen' ]) def get_image( self , x, y, width, height, dest, sprite_sheet): """Returns images and rects to blit onto the screen""" image = pg.Surface([width, height]) rect = image.get_rect() image.blit(sprite_sheet, ( 0 , 0 ), (x, y, width, height)) if sprite_sheet = = setup.GFX[ 'title_screen' ]: image.set_colorkey(( 255 , 0 , 220 )) image = pg.transform.scale(image, ( int (rect.width * c.SIZE_MULTIPLIER), int (rect.height * c.SIZE_MULTIPLIER))) else : image.set_colorkey(c.BLACK) image = pg.transform.scale(image, ( int (rect.width * 3 ), int (rect.height * 3 ))) rect = image.get_rect() rect.x = dest[ 0 ] rect.y = dest[ 1 ] return (image, rect) def update( self , surface, keys, current_time): """Updates the state every refresh""" self .current_time = current_time self .game_info[c.CURRENT_TIME] = self .current_time self .update_cursor(keys) self .overhead_info.update( self .game_info) surface.blit( self .background, self .viewport, self .viewport) surface.blit( self .image_dict[ 'GAME_NAME_BOX' ][ 0 ], self .image_dict[ 'GAME_NAME_BOX' ][ 1 ]) surface.blit( self .mario.image, self .mario.rect) surface.blit( self .cursor.image, self .cursor.rect) self .overhead_info.draw(surface) def update_cursor( self , keys): """Update the position of the cursor""" input_list = [pg.K_RETURN, pg.K_a, pg.K_s] if self .cursor.state = = c.PLAYER1: self .cursor.rect.y = 358 if keys[pg.K_DOWN]: self .cursor.state = c.PLAYER2 for input in input_list: if keys[ input ]: self .reset_game_info() self .done = True elif self .cursor.state = = c.PLAYER2: self .cursor.rect.y = 403 if keys[pg.K_UP]: self .cursor.state = c.PLAYER1 def reset_game_info( self ): """Resets the game info in case of a Game Over and restart""" self .game_info[c.COIN_TOTAL] = 0 self .game_info[c.SCORE] = 0 self .game_info[c.LIVES] = 3 self .game_info[c.CURRENT_TIME] = 0.0 self .game_info[c.LEVEL_STATE] = None self .persist = self .game_info |
5.main()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
from . import setup,tools from .states import main_menu,load_screen,level1 from . import constants as c def main(): """Add states to control here.""" run_it = tools.Control(setup.ORIGINAL_CAPTION) state_dict = {c.MAIN_MENU: main_menu.Menu(), c.LOAD_SCREEN: load_screen.LoadScreen(), c.TIME_OUT: load_screen.TimeOut(), c.GAME_OVER: load_screen.GameOver(), c.LEVEL1: level1.Level1()} run_it.setup_states(state_dict, c.MAIN_MENU) run_it.main() |
6.调用以上函数实现
1
2
3
4
5
6
7
8
9
10
|
import sys import pygame as pg from 小游戏.超级玛丽.data.main import main import cProfile if __name__ = = '__main__' : main() pg.quit() sys.exit() |
以上就是基于Python实现超级玛丽游戏的示例代码的详细内容,更多关于Python超级玛丽的资料请关注服务器之家其它相关文章!
原文链接:https://blog.csdn.net/m0_70127749/article/details/124581389