pygame--超级马里奥(万字详细版)

3c1598e96a264e0989519bdac21e9b14.gif

超级马里奥点我下载https://github.com/marblexu/PythonSuperMario

 1.游戏介绍

小时候的经典游戏,代码参考了github上的项目Mario-Level-1,使用pygame来实现,从中学习到了横版过关游戏实现中的一些处理方法。原项目实现了超级玛丽的第一个小关。

在原项目的基础上,游戏使用json文件来保存每一个关卡的数据,将数据和代码解耦合,目前已开发4个小关,后续关卡的扩展也很方便,只需要添加json文件和地图图片,支持新的怪物就行。游戏还支持进入水管,到新的子地图。

这篇文章是要介绍下游戏中的几个界面显示和界面之前如何转换,所以特意写了一个demo程序,完整的游戏代码在下面的github链接中下载。

2.状态介绍

游戏中的状态机一般都是有限状态机,简写为FSM(Finite State Machine),简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。
状态机的每一个状态至少需要有下面三个操作:

Startup:当从其他状态进入这个状态时,需要进行的初始化操作

Update :在这个状态运行时进行的更新操作
Cleanup:当从这个状态退出时,需要进行的清除操作
状态需要的变量:

next: 表示这个状态退出后要转到的下一个状态
persist:在状态间转换时需要传递的数据
done:表示这个状态是否结束,状态机会根据这个值来决定转换状态

c645dbda38c24f43884393c40623c8b8.png

 

状态机代码实现

因为这篇文章的目的是游戏界面的状态机实现,所以专门写了一个state_demo.py文件,让大家可以更加方便的看代码。

游戏启动代码

开始是 pygame的初始化,设置屏幕大小为c.SCREEN_SIZE(800, 600)。所有的常量都保存在单独的constants.py中。

import os
import pygame as pg
import constants as cpg.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()

 oad_all_gfx函数查找指定目录下所有符合后缀名的图片,使用pg.image.load函数加载,保存在graphics set中。
GFX 保存在resources/graphics目录找到的所有图片,后面获取各种图形时会用到。

def load_all_gfx(directory, colorkey=(255,0,255), accept=('.png', '.jpg', '.bmp', '.gif')):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] = imgreturn graphicsGFX = load_all_gfx(os.path.join("resources","graphics"))

 下面是demo的入口函数,先创建了一个保存所有状态的state_dict set,调用setup_states函数设置起始状态是 MAIN_MENU。

if __name__=='__main__':game = Control()state_dict = {c.MAIN_MENU: Menu(),c.LOAD_SCREEN: LoadScreen(),c.LEVEL: Level(),c.GAME_OVER: GameOver(),c.TIME_OUT: TimeOut()}game.setup_states(state_dict, c.MAIN_MENU)game.main()

 

状态类

先定义一个State 基类, 按照上面说的状态需要的三个操作分别定义函数(startup, update, cleanup)。在 init 函数中定义了上面说的三个变量(next,persist,done),还有start_time 和 current_time 用于记录时间。

class State():def __init__(self):self.start_time = 0.0self.current_time = 0.0self.done = Falseself.next = Noneself.persist = {}@abstractmethoddef startup(self, current_time, persist):'''abstract method'''def cleanup(self):self.done = Falsereturn self.persist@abstractmethoddef update(sefl, surface, keys, current_time):'''abstract method'''

info类

下面介绍Info类,界面的显示大部分都是由它来完成,init函数中create_info_labels函数创建通用的信息,create_state_labels函数对于不同的状态,会初始化不同的信息。

class Info():def __init__(self, game_info, state):self.coin_total = game_info[c.COIN_TOTAL]self.total_lives = game_info[c.LIVES]self.state = stateself.game_info = game_infoself.create_font_image_dict()self.create_info_labels()self.create_state_labels()self.flashing_coin = FlashCoin(280, 53)

 

Control类

Control 是状态机类,main函数是游戏的主循环,setup_states函数设置游戏启动时运行的状态

class Control():def __init__(self):self.screen = pg.display.get_surface()self.done = Falseself.clock = pg.time.Clock()self.fps = 60self.current_time = 0.0self.keys = pg.key.get_pressed()self.state_dict = {}self.state_name = Noneself.state = Nonedef setup_states(self, state_dict, start_state):self.state_dict = state_dictself.state_name = start_stateself.state = self.state_dict[self.state_name]def main(self):while not self.done:self.event_loop()self.update()pg.display.update()self.clock.tick(self.fps)

3.完整源码

constants.py

我设置的游戏时间是300秒,也可以改。

SCREEN_HEIGHT = 600
SCREEN_WIDTH = 800
SCREEN_SIZE = (SCREEN_WIDTH,SCREEN_HEIGHT)ORIGINAL_CAPTION = "Super Mario Bros"GAME_TIME_OUT = 5## COLORS ##
#                R    G    B
BLACK        = (  0,   0,   0)SIZE_MULTIPLIER = 2.5
BRICK_SIZE_MULTIPLIER = 2.69
BACKGROUND_MULTIPLER = 2.679
GROUND_HEIGHT = SCREEN_HEIGHT - 62#STATES FOR ENTIRE GAME
MAIN_MENU = 'main menu'
LOAD_SCREEN = 'load screen'
TIME_OUT = 'time out'
GAME_OVER = 'game over'
LEVEL = 'level'#MAIN MENU CURSOR STATES
PLAYER1 = '1 PLAYER GAME'
PLAYER2 = '2 PLAYER GAME'#GAME INFO DICTIONARY KEYS
COIN_TOTAL = 'coin total'
SCORE = 'score'
TOP_SCORE = 'top score'
LIVES = 'lives'
CURRENT_TIME = 'current time'
LEVEL_NUM = 'level num'
PLAYER_NAME = 'player name'
PLAYER_MARIO = 'mario'
PLAYER_LUIGI = 'luigi'ITEM_SHEET = 'item_objects'

 state_demo.py

import os
import pygame as pg
from abc import ABC, abstractmethod
import constants as cclass State():def __init__(self):self.start_time = 0.0self.current_time = 0.0self.done = Falseself.next = Noneself.persist = {}@abstractmethoddef startup(self, current_time, persist):'''abstract method'''def cleanup(self):self.done = Falsereturn self.persist@abstractmethoddef update(sefl, surface, keys, current_time):'''abstract method'''class Menu(State):def __init__(self):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_NUM: 1,c.PLAYER_NAME: c.PLAYER_MARIO}self.startup(0.0, persist)def startup(self, current_time, persist):self.next = c.LOAD_SCREENself.persist = persistself.game_info = persistself.overhead_info = Info(self.game_info, c.MAIN_MENU)self.setup_background()self.setup_player()self.setup_cursor()def setup_background(self):self.background = 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 = SCREEN.get_rect(bottom=SCREEN_RECT.bottom)self.image_dict = {}image = get_image(GFX['title_screen'], 1, 60, 176, 88,(255, 0, 220), c.SIZE_MULTIPLIER)rect = image.get_rect()rect.x, rect.y = (170, 100)self.image_dict['GAME_NAME_BOX'] = (image, rect)def setup_player(self):self.player_list = []player_rect_info = [(178, 32, 12, 16), (178, 128, 12, 16)]for rect in player_rect_info:image = get_image(GFX['mario_bros'],*rect, c.BLACK, 2.9)rect = image.get_rect()rect.x, rect.bottom = 110, c.GROUND_HEIGHTself.player_list.append((image, rect))self.player_index = 0def setup_cursor(self):self.cursor = pg.sprite.Sprite()self.cursor.image = get_image(GFX[c.ITEM_SHEET], 24, 160, 8, 8, c.BLACK, 3)rect = self.cursor.image.get_rect()rect.x, rect.y = (220, 358)self.cursor.rect = rectself.cursor.state = c.PLAYER1def update(self, surface, keys, current_time):self.current_time = current_timeself.game_info[c.CURRENT_TIME] = self.current_timeself.player_image = self.player_list[self.player_index][0]self.player_rect = self.player_list[self.player_index][1]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.player_image, self.player_rect)surface.blit(self.cursor.image, self.cursor.rect)self.overhead_info.draw(surface)def update_cursor(self, keys):if self.cursor.state == c.PLAYER1:self.cursor.rect.y = 358if keys[pg.K_DOWN]:self.cursor.state = c.PLAYER2self.player_index = 1self.game_info[c.PLAYER_NAME] = c.PLAYER_LUIGIelif self.cursor.state == c.PLAYER2:self.cursor.rect.y = 403if keys[pg.K_UP]:self.cursor.state = c.PLAYER1self.player_index = 0self.game_info[c.PLAYER_NAME] = c.PLAYER_MARIOif keys[pg.K_RETURN]:self.done = Trueclass LoadScreen(State):def __init__(self):State.__init__(self)self.time_list = [2400, 2600, 2635]def startup(self, current_time, persist):self.start_time = current_timeself.persist = persistself.game_info = self.persistself.next = self.set_next_state()info_state = self.set_info_state()self.overhead_info = Info(self.game_info, info_state)def set_next_state(self):return c.LEVELdef set_info_state(self):return c.LOAD_SCREENdef update(self, surface, keys, current_time):if (current_time - self.start_time) < self.time_list[0]:surface.fill(c.BLACK)self.overhead_info.update(self.game_info)self.overhead_info.draw(surface)elif (current_time - self.start_time) < self.time_list[1]:surface.fill(c.BLACK)elif (current_time - self.start_time) < self.time_list[2]:surface.fill((106, 150, 252))else:self.done = Trueclass GameOver(LoadScreen):def __init__(self):LoadScreen.__init__(self)self.time_list = [3000, 3200, 3235]def set_next_state(self):return c.MAIN_MENUdef set_info_state(self):return c.GAME_OVERclass TimeOut(LoadScreen):def __init__(self):LoadScreen.__init__(self)self.time_list = [2400, 2600, 2635]def set_next_state(self):if self.persist[c.LIVES] == 0:return c.GAME_OVERelse:return c.LOAD_SCREENdef set_info_state(self):return c.TIME_OUTclass Level(State):def __init__(self):State.__init__(self)def startup(self, current_time, persist):self.game_info = persistself.persist = self.game_infoself.player = Noneself.overhead_info = Info(self.game_info, c.LEVEL)self.setup_background()def setup_background(self):self.background = GFX['level_1']self.bg_rect = self.background.get_rect()self.background = pg.transform.scale(self.background, (int(self.bg_rect.width*c.BACKGROUND_MULTIPLER),int(self.bg_rect.height*c.BACKGROUND_MULTIPLER)))self.bg_rect = self.background.get_rect()self.level = pg.Surface((self.bg_rect.w, self.bg_rect.h)).convert()self.viewport = SCREEN.get_rect(bottom=self.bg_rect.bottom)def update(self, surface, keys, current_time):self.game_info[c.CURRENT_TIME] = self.current_time = current_timeself.overhead_info.update(self.game_info, self.player)if self.overhead_info.time <= 0:self.update_game_info()self.done = Trueself.draw(surface)def update_game_info(self):self.persist[c.LIVES] -= 1if self.persist[c.LIVES] == 0:self.next = c.GAME_OVERelif self.overhead_info.time == 0:self.next = c.TIME_OUTelse:self.next = c.LOAD_SCREENdef draw(self, surface):self.level.blit(self.background, self.viewport, self.viewport)surface.blit(self.level, (0,0), self.viewport)self.overhead_info.draw(surface)class Character(pg.sprite.Sprite):def __init__(self, image):pg.sprite.Sprite.__init__(self)self.image = imageself.rect = self.image.get_rect()class Info():def __init__(self, game_info, state):self.coin_total = game_info[c.COIN_TOTAL]self.total_lives = game_info[c.LIVES]self.state = stateself.game_info = game_infoself.create_font_image_dict()self.create_info_labels()self.create_state_labels()self.flashing_coin = FlashCoin(280, 53)def create_font_image_dict(self):self.image_dict = {}image_list = []image_rect_list = [# 0 - 9(3, 230, 7, 7), (12, 230, 7, 7), (19, 230, 7, 7),(27, 230, 7, 7), (35, 230, 7, 7), (43, 230, 7, 7),(51, 230, 7, 7), (59, 230, 7, 7), (67, 230, 7, 7),(75, 230, 7, 7), # A - Z(83, 230, 7, 7), (91, 230, 7, 7), (99, 230, 7, 7),(107, 230, 7, 7), (115, 230, 7, 7), (123, 230, 7, 7),(3, 238, 7, 7), (11, 238, 7, 7), (20, 238, 7, 7),(27, 238, 7, 7), (35, 238, 7, 7), (44, 238, 7, 7),(51, 238, 7, 7), (59, 238, 7, 7), (67, 238, 7, 7),(75, 238, 7, 7), (83, 238, 7, 7), (91, 238, 7, 7),(99, 238, 7, 7), (108, 238, 7, 7), (115, 238, 7, 7),(123, 238, 7, 7), (3, 246, 7, 7), (11, 246, 7, 7),(20, 246, 7, 7), (27, 246, 7, 7), (48, 246, 7, 7),# -*(68, 249, 6, 2), (75, 247, 6, 6)]character_string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ -*'for character, image_rect in zip(character_string, image_rect_list):self.image_dict[character] = get_image(GFX['text_images'], *image_rect, (92, 148, 252), 2.9)def create_info_labels(self):self.score_text = []self.coin_count_text = []self.mario_label = []self.world_label = []self.time_label = []self.stage_label = []self.create_label(self.score_text, '000000', 75, 55)self.create_label(self.coin_count_text, '*00', 300, 55)self.create_label(self.mario_label, 'MARIO', 75, 30)self.create_label(self.world_label, 'WORLD', 450, 30)self.create_label(self.time_label, 'TIME', 625, 30)self.create_label(self.stage_label, '1-1', 472, 55)self.info_labels = [self.score_text, self.coin_count_text, self.mario_label,self.world_label, self.time_label, self.stage_label]def create_state_labels(self):if self.state == c.MAIN_MENU:self.create_main_menu_labels()elif self.state == c.LOAD_SCREEN:self.create_player_image()self.create_load_screen_labels()elif self.state == c.LEVEL:self.create_level_labels()elif self.state == c.GAME_OVER:self.create_game_over_labels()elif self.state == c.TIME_OUT:self.create_time_out_labels()def create_player_image(self):self.life_times_image = get_image(GFX['text_images'], 75, 247, 6, 6, (92, 148, 252), 2.9)self.life_times_rect = self.life_times_image.get_rect(center=(378, 295))self.life_total_label = []self.create_label(self.life_total_label, str(self.total_lives), 450, 285)if self.game_info[c.PLAYER_NAME] == c.PLAYER_MARIO:rect = (178, 32, 12, 16)else:rect = (178, 128, 12, 16)self.player_image = get_image(GFX['mario_bros'], *rect, (92, 148, 252), 2.9)self.player_rect = self.player_image.get_rect(center=(320, 290))def create_main_menu_labels(self):mario_game = []luigi_game = []top = []top_score = []self.create_label(mario_game, c.PLAYER1, 272, 360)self.create_label(luigi_game, c.PLAYER2, 272, 405)self.create_label(top, 'TOP - ', 290, 465)self.create_label(top_score, '000000', 400, 465)self.state_labels = [mario_game, luigi_game, top, top_score,*self.info_labels]def create_load_screen_labels(self):world_label = []self.stage_label2 = []self.create_label(world_label, 'WORLD', 280, 200)self.create_label(self.stage_label2, '1-1', 430, 200)self.state_labels = [world_label, self.stage_label2,*self.info_labels, self.life_total_label]def create_level_labels(self):self.time = c.GAME_TIME_OUTself.current_time = 0self.clock_time_label = []self.create_label(self.clock_time_label, str(self.time), 645, 55)self.state_labels = [*self.info_labels, self.clock_time_label]def create_game_over_labels(self):game_label = []over_label = []self.create_label(game_label, 'GAME', 280, 300)self.create_label(over_label, 'OVER', 400, 300)self.state_labels = [game_label, over_label, *self.info_labels]def create_time_out_labels(self):timeout_label = []self.create_label(timeout_label, 'TIME OUT', 290, 310)self.state_labels = [timeout_label, *self.info_labels]def create_label(self, label_list, string, x, y):for letter in string:label_list.append(Character(self.image_dict[letter]))self.set_label_rects(label_list, x, y)def set_label_rects(self, label_list, x, y):for i, letter in enumerate(label_list):letter.rect.x = x + ((letter.rect.width + 3) * i)letter.rect.y = yif letter.image == self.image_dict['-']:letter.rect.y += 7letter.rect.x += 2def update(self, level_info, level=None):self.level = levelself.handle_level_state(level_info)def handle_level_state(self, level_info):self.score = level_info[c.SCORE]self.update_text(self.score_text, self.score)self.update_text(self.coin_count_text, level_info[c.COIN_TOTAL])self.update_text(self.stage_label, level_info[c.LEVEL_NUM])self.flashing_coin.update(level_info[c.CURRENT_TIME])if self.state == c.LOAD_SCREEN:self.update_text(self.stage_label2, level_info[c.LEVEL_NUM])if self.state == c.LEVEL:if (level_info[c.CURRENT_TIME] - self.current_time) > 1000:self.current_time = level_info[c.CURRENT_TIME]self.time -= 1self.update_text(self.clock_time_label, self.time, True)def update_text(self, text, score, reset=False):if reset and len(text) > len(str(score)):text.remove(text[0])index = len(text) - 1for digit in reversed(str(score)):rect = text[index].recttext[index] = Character(self.image_dict[digit])text[index].rect = rectindex -= 1def draw(self, surface):self.draw_info(surface, self.state_labels)if self.state == c.LOAD_SCREEN:surface.blit(self.player_image, self.player_rect)surface.blit(self.life_times_image, self.life_times_rect)surface.blit(self.flashing_coin.image, self.flashing_coin.rect)def draw_info(self, surface, label_list):for label in label_list:for letter in label:surface.blit(letter.image, letter.rect)class FlashCoin(pg.sprite.Sprite):def __init__(self, x, y):pg.sprite.Sprite.__init__(self)self.frame_index = 0self.frames = []self.load_frames()self.image = self.frames[self.frame_index]self.rect = self.image.get_rect()self.rect.x = xself.rect.y = yself.animation_timer = 0def load_frames(self):sheet = GFX[c.ITEM_SHEET]frame_rect_list = [(1, 160, 5, 8), (9, 160, 5, 8),(17, 160, 5, 8), (9, 160, 5, 8)]for frame_rect in frame_rect_list:self.frames.append(get_image(sheet, *frame_rect, c.BLACK, c.BRICK_SIZE_MULTIPLIER))def update(self, current_time):time_list = [375, 125, 125, 125]if self.animation_timer == 0:self.animation_timer = current_timeelif (current_time - self.animation_timer) > time_list[self.frame_index]:self.frame_index += 1if self.frame_index == 4:self.frame_index = 0self.animation_timer = current_timeself.image = self.frames[self.frame_index]class Control():def __init__(self):self.screen = pg.display.get_surface()self.done = Falseself.clock = pg.time.Clock()self.fps = 60self.current_time = 0.0self.keys = pg.key.get_pressed()self.state_dict = {}self.state_name = Noneself.state = Nonedef setup_states(self, state_dict, start_state):self.state_dict = state_dictself.state_name = start_stateself.state = self.state_dict[self.state_name]def update(self):self.current_time = pg.time.get_ticks()if 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.nextpersist = self.state.cleanup()self.state = self.state_dict[self.state_name]self.state.startup(self.current_time, persist)def event_loop(self):for event in pg.event.get():if event.type == pg.QUIT:self.done = Trueelif event.type == pg.KEYDOWN:self.keys = pg.key.get_pressed()elif event.type == pg.KEYUP:self.keys = pg.key.get_pressed()def main(self):while not self.done:self.event_loop()self.update()pg.display.update()self.clock.tick(self.fps)def get_image(sheet, x, y, width, height, colorkey, scale):image = pg.Surface([width, height])rect = image.get_rect()image.blit(sheet, (0, 0), (x, y, width, height))image.set_colorkey(colorkey)image = pg.transform.scale(image,(int(rect.width*scale),int(rect.height*scale)))return imagedef load_all_gfx(directory, colorkey=(255,0,255), accept=('.png', '.jpg', '.bmp', '.gif')):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] = imgreturn graphics# pygame related initial code 
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()GFX = load_all_gfx(os.path.join("resources","graphics"))if __name__=='__main__':game = Control()state_dict = {c.MAIN_MENU: Menu(),c.LOAD_SCREEN: LoadScreen(),c.LEVEL: Level(),c.GAME_OVER: GameOver(),c.TIME_OUT: TimeOut()}game.setup_states(state_dict, c.MAIN_MENU)game.main()

需要的图片 

1.10b371b1b74f482dae26cb890edf417c.png

2.

c5088eb3e34b4d91b6f6e82de7bdecbd.png3.

81572bb2f5a1474a9b5435f63228133c.png4.

4b5adf1d3ec3425db6798072f629cb67.png5.

1a5b9b8435314e98b7e32761329d6dad.png6.

c90f15734aba441e872067267879f079.png

7.a13ea2d739c6480ba05ed62582effe60.png

8.d660650a9d92472ebcbec4bd1268bab7.png 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/438977.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用vue-capper封装一个可以函数式调用图片裁剪组件

1. 效果 const cropData await wqCrop({prop:{img,autoCrop: true, // 是否开启截图框maxImgSize: 600,autoCropWidth: 30,canMove: true, // 图片是否可移动canMoveBox: true, // 截图框是否可移动fixedBox: false, // 截图框是否固定}});console.log(cropData);使用wqCrop会…

virtualbox配置为NAT模式后物理机和虚拟机互通

virtualbox配置为 NAT模式后&#xff0c;虚拟机分配到的 IP地址一般是 10.xx网段的&#xff0c;虚拟机可以通过网络地址转换访问物理机所在的网络&#xff0c;但若不做任何配置&#xff0c;则物理机无法直接访问虚拟机。 virtualbox在提供 NAT配置模式时&#xff0c;也提供了端…

重置linux后vscode无法再次使用ssh连接

如果你使用过vscode ssh远程连接了一个Linux系统&#xff0c;但该系统被重置了&#xff0c;并且关键配置没有改变。再次使用vscode连接时&#xff0c;vscode可能无法连接。 原因&#xff1a;vscode远程连接后会在C:\Users{{你的用户名}}.ssh下的known_hosts和known_hosts.old。…

osg 矩阵相关

下面结果是一样的 osg::Matrix mtrixx;mtrixx.makeRotate(90 / 180.f * osg::PI, osg::Vec3(1, 0, 0));osg::Matrix mtrixx12 osg::Matrix::rotate(90 / 180.f * osg::PI, 1, 0, 0); 下面结果是一样 osg::Matrix m1;m1.makeTranslate(osg::Vec3(18, 12,3));osg::Matrix m2 os…

QT系统学习篇(2)- Qt跨平台GUI原理机制

一、Qt工程管理 1、新建项目&#xff1a; 我们程序员新建项目对话框所有5类项目模板 Application: Qt的应用程序&#xff0c;包含Qt Quick和普通窗口程序。 Library: 它可以创建动态库、静态库、Qt Creator自身插件、Qt Quick扩展插件。 其他项目: 创建单元测试项目、子目录项…

hackmyvm-Nubula靶机

主机发现 sudo arp-scan -l 以sudo超级管理员权限运行arp-scan 扫描整个局域网 -l扫描本地网络的所有网段 发现靶机ip&#xff1a;192.168.91.208 nmap对靶机进行端口扫描发现22和80端口 22&#xff1a;进行ssh远程登录的开放端口 80&#xff1a;超文本传输协议的web服务…

【leetcode】 45.跳跃游戏 ||

如果我们「贪心」地进行正向查找&#xff0c;每次找到可到达的最远位置&#xff0c;就可以在线性时间内得到最少的跳跃次数。 例如&#xff0c;对于数组 [2,3,1,2,4,2,3]&#xff0c;初始位置是下标 0&#xff0c;从下标 0 出发&#xff0c;最远可到达下标 2。下标 0 可到达的…

vue3学习:axios输入城市名称查询该城市天气

说来惭愧&#xff0c;接触前端也有很长一段时间了&#xff0c;最近才学习axios与后端的交互。今天学习了一个查询城市天气的案例&#xff0c;只需输入城市名称&#xff0c;点击“查询”按钮便可以进行查询。运行效果如下&#xff1a; 案例只实现了基本的查询功能&#xff0c;没…

华为OD机试 - 可活动的最大网格点数目 - 广度优先搜索BFS(Python/JS/C/C++ 2024 E卷 200分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

【C++打怪之路Lv6】-- 内存管理

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;C打怪之路&#xff0c;python从入门到精通&#xff0c;数据结构&#xff0c;C语言&#xff0c;C语言题集&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文(平均质量分82)&#…

【重学 MySQL】五十一、更新和删除数据

【重学 MySQL】五十一、更新和删除数据 更新数据删除数据注意事项 在MySQL中&#xff0c;更新和删除数据是数据库管理的基本操作。 更新数据 为了更新&#xff08;修改&#xff09;表中的数据&#xff0c;可使用UPDATE语句。UPDATE语句的基本语法如下&#xff1a; UPDATE ta…

[Python学习日记-33] Python 中的嵌套函数、匿名函数和高阶函数

[Python学习日记-33] Python 中的嵌套函数、匿名函数和高阶函数 简介 嵌套函数 匿名函数 高阶函数 简介 在 Python 当中函数除了能减少重复代码、扩展性强和易维护外&#xff0c;其实还有挺多不通的玩法的&#xff0c;例如嵌套函数、匿名函数、高阶函数等&#xff0c;它们是…

C# 无边框窗体,加阴影效果、多组件拖动、改变大小等功能完美实现优化版效果体验

一、预览效果 国庆节第一天,祝祖国繁荣昌盛! 1.1 效果图 (WinForm无边框窗体,F11可全屏) 拖动窗体时半透明效果(拖动时参考窗体后面释放位置) 说明:本功能的实现基于网友的原型完善而来,更多代码可以参考他的文章 h

图解大模型计算加速系列:vLLM源码解析3,Prefix Caching

【全文目录如下】 一、两种不同的BlockAllocator 二、物理块和逻辑块的结构 三、prefill阶段的物理块分配方法 3.1 allocate函数入口 3.2 计算物理块hash值的方法 3.3 使用LRUEvictor管理物理块分配细节 3.4 再探LRUEvictor&#xff0c;理解“prefix” …

Elasticsearch学习记录

阅读前须知 本文通过安装elasticsearch-7.17.0为基础&#xff0c;使用 kibana-7.17.0 对 elasticsearch 进行操作&#xff0c;本文中 es 是对 elasticsearch 的简写。 下载地址&#xff1a;elasticsearch_免费高速下载|百度网盘-分享无限制 (baidu.com) 1 初识Elasticsearch …

阿里巴巴开源的FastJson 1反序列化漏洞复现攻击保姆级教程

免责申明 本文仅是用于学习检测自己搭建的靶场环境有关FastJson1反序列化漏洞的原理和攻击实验,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》‌及其所在…

【重学 MySQL】四十五、数据库的创建、修改与删除

【重学 MySQL】四十五、数据库的创建、修改与删除 一条数据存储的过程数据输入数据验证数据处理数据存储数据持久化反馈与日志注意事项 标识符命名规则基本规则长度限制保留字与特殊字符命名建议示例 MySQL 中的数据类型创建数据库创建数据库时指定字符集和排序规则 查看数据库…

Ubuntu安装Hadoop3.4

1、创建Hadoop用户 sudo adduser hadoop 将Hadoop加进sudo用户组,赋予更高权限: sudo usermod -G sudo hadoop 3、安装JDK(略) 查看JDK安装路径:which java 和 ls -al 3、配置SSH免密登录 在Hadoop分布式集群环境中,各个机器之间的通信通常需要使用SSH的方式进行连…

探索Python网络世界的利器:Requests-HTML库

文章目录 探索Python网络世界的利器&#xff1a;Requests-HTML库背景&#xff1a;为何选择Requests-HTML&#xff1f;什么是Requests-HTML&#xff1f;如何安装Requests-HTML&#xff1f;5个简单库函数的使用方法3个场景下库的使用示例常见Bug及解决方案总结 探索Python网络世界…

【多线程】多线程(8):单例模式:阻塞队列

【阻塞队列】 阻塞队列是在普通的“先进先出”队列的基础上&#xff0c;做出了扩充&#xff0c;可以组成「生产者消费者模型」 1.线程安全性 标准库是原有的队列Queue和其子类&#xff0c;默认都是“线程不安全的”&#xff0c;而阻塞队列是“线程安全的” 2.具有阻塞特性 …