दिलचस्प पोस्ट
रनटाइम पर इकाई फ्रेमवर्क परिवर्तन कनेक्शन MySQL में सभी प्रश्नों को लॉग इन करें लीगेंड को ggplot2 लाइन प्लॉट के लिए जोड़ें 4xcode में पायथन? PHP के साथ एक निर्देशिका में सभी फाइलों के नाम प्राप्त करना क्या सी / सी ++ में एक मानक साइन फंक्शन (सिग्गम, एसजीएन) है? क्या किसी थ्रेड (थ्रेड। अपॉर्टेन्ट विधि) को छोड़ने जैसे कार्य को रद्द करना संभव है? एचटीएमएल टैग निकालें लेकिन अंदरूनी HTML रखें स्टोरीबोर्ड में, मैं एक से अधिक नियंत्रकों के साथ कस्टम सेल कैसे बनाऊं? गूंज "#!" विफल – "घटना नहीं मिला" एक MySQL तालिका में डालें या अपडेट करें तत्वों के क्रम में "for (… in …)" लूप 'करीइंग' क्या है? क्या कोई सी ++ क्लास स्वयं एक विशेषता के रूप में शामिल हो सकता है? सूची .__ iadd__ और सूची .__ add__ के लिए अलग व्यवहार

पैगमेम में एक प्लेटफॉर्म पर स्क्रॉल करना जोड़ें

ठीक है, मैंने अपनी परियोजना के लिए नीचे दिए गए कोड को शामिल किया, मैं सिर्फ एक प्लेटफार्म बनाने पर कुछ प्रयोग कर रहा हूं। मैं यह समझाने की कोशिश कर रहा हूं कि खिलाड़ी के अनुसरण में कुछ सरल सरल स्क्रॉल करने के लिए, इसलिए खिलाड़ी कैमरे का केंद्र है और उसे बाउंस / उसके अनुसरण करता है क्या कोई मेरी मदद कर सकता है?

import pygame from pygame import * WIN_WIDTH = 800 WIN_HEIGHT = 640 HALF_WIDTH = int(WIN_WIDTH / 2) HALF_HEIGHT = int(WIN_HEIGHT / 2) DISPLAY = (WIN_WIDTH, WIN_HEIGHT) DEPTH = 32 FLAGS = 0 CAMERA_SLACK = 30 def main(): global cameraX, cameraY pygame.init() screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH) pygame.display.set_caption("Use arrows to move!") timer = pygame.time.Clock() up = down = left = right = running = False bg = Surface((32,32)) bg.convert() bg.fill(Color("#000000")) entities = pygame.sprite.Group() player = Player(32, 32) platforms = [] x = y = 0 level = [ "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP", "PP", "PP", "PP", "PP", "PP", "PP", "PP", "P PPPPPPPPPPP P", "PP", "PP", "PP", "PP", "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",] # build the level for row in level: for col in row: if col == "P": p = Platform(x, y) platforms.append(p) entities.add(p) if col == "E": e = ExitBlock(x, y) platforms.append(e) entities.add(e) x += 32 y += 32 x = 0 entities.add(player) while 1: timer.tick(60) for e in pygame.event.get(): if e.type == QUIT: raise SystemExit, "QUIT" if e.type == KEYDOWN and e.key == K_ESCAPE: raise SystemExit, "ESCAPE" if e.type == KEYDOWN and e.key == K_UP: up = True if e.type == KEYDOWN and e.key == K_DOWN: down = True if e.type == KEYDOWN and e.key == K_LEFT: left = True if e.type == KEYDOWN and e.key == K_RIGHT: right = True if e.type == KEYDOWN and e.key == K_SPACE: running = True if e.type == KEYUP and e.key == K_UP: up = False if e.type == KEYUP and e.key == K_DOWN: down = False if e.type == KEYUP and e.key == K_RIGHT: right = False if e.type == KEYUP and e.key == K_LEFT: left = False if e.type == KEYUP and e.key == K_RIGHT: right = False # draw background for y in range(32): for x in range(32): screen.blit(bg, (x * 32, y * 32)) # update player, draw everything else player.update(up, down, left, right, running, platforms) entities.draw(screen) pygame.display.update() class Entity(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) class Player(Entity): def __init__(self, x, y): Entity.__init__(self) self.xvel = 0 self.yvel = 0 self.onGround = False self.image = Surface((32,32)) self.image.fill(Color("#0000FF")) self.image.convert() self.rect = Rect(x, y, 32, 32) def update(self, up, down, left, right, running, platforms): if up: # only jump if on the ground if self.onGround: self.yvel -= 10 if down: pass if running: self.xvel = 12 if left: self.xvel = -8 if right: self.xvel = 8 if not self.onGround: # only accelerate with gravity if in the air self.yvel += 0.3 # max falling speed if self.yvel > 100: self.yvel = 100 if not(left or right): self.xvel = 0 # increment in x direction self.rect.left += self.xvel # do x-axis collisions self.collide(self.xvel, 0, platforms) # increment in y direction self.rect.top += self.yvel # assuming we're in the air self.onGround = False; # do y-axis collisions self.collide(0, self.yvel, platforms) def collide(self, xvel, yvel, platforms): for p in platforms: if pygame.sprite.collide_rect(self, p): if isinstance(p, ExitBlock): pygame.event.post(pygame.event.Event(QUIT)) if xvel > 0: self.rect.right = p.rect.left print "collide right" if xvel < 0: self.rect.left = p.rect.right print "collide left" if yvel > 0: self.rect.bottom = p.rect.top self.onGround = True self.yvel = 0 if yvel < 0: self.rect.top = p.rect.bottom class Platform(Entity): def __init__(self, x, y): Entity.__init__(self) self.image = Surface((32, 32)) self.image.convert() self.image.fill(Color("#DDDDDD")) self.rect = Rect(x, y, 32, 32) def update(self): pass class ExitBlock(Platform): def __init__(self, x, y): Platform.__init__(self, x, y) self.image.fill(Color("#0033FF")) if __name__ == "__main__": main() 

वेब के समाधान से एकत्रित समाधान "पैगमेम में एक प्लेटफॉर्म पर स्क्रॉल करना जोड़ें"

आपको उन्हें खींचने पर अपनी संस्थाओं की स्थिति को ऑफसेट करना होगा। चलो एक camera ऑफसेट कहते हैं, क्योंकि यह हम इस के साथ प्राप्त करना चाहते प्रभाव है।

सबसे पहले, हम प्रेत समूह के draw फ़ंक्शन का उपयोग (और नहीं करना चाहिए) नहीं कर सकते, क्योंकि प्रेतों को यह जानने की जरूरत नहीं है कि उनकी स्थिति ( rect ) स्क्रीन पर खींची जाने वाली स्थिति नहीं है (निश्चित तौर पर हम Group वर्ग को उप-वर्ग बना सकते हैं और कैमरे के बारे में जागरूक होने के लिए इसे draw करने के draw पुनः अनुपूरक कर सकते हैं, लेकिन सीखने के लिए चलो यहाँ स्पष्ट होना)।


आइए हम ऑफसेट की स्थिति को पकड़ने के लिए एक Camera क्लास बनाकर शुरू करें, हम अपनी संस्थाओं की स्थिति पर आवेदन करना चाहते हैं:

 class Camera(object): def __init__(self, camera_func, width, height): self.camera_func = camera_func self.state = Rect(0, 0, width, height) def apply(self, target): return target.rect.move(self.state.topleft) def update(self, target): self.state = self.camera_func(self.state, target.rect) 

कुछ बातों को यहां नोट करने के लिए:

हमें कैमरे की स्थिति और पिक्सल में स्तर की चौड़ाई और ऊंचाई को संग्रहित करने की आवश्यकता है (चूंकि हम स्तर के किनारों पर स्क्रॉल करना बंद करना चाहते हैं)। मैंने इन सभी सूचनाओं को संग्रहीत करने के लिए Rect का इस्तेमाल किया था, लेकिन आप आसानी से कुछ फ़ील्ड का उपयोग कर सकते हैं।

Rect का उपयोग करना समारोह में apply है। यह वह जगह है जहां हम स्क्रॉलिंग को लागू करने के लिए स्क्रीन पर एक इकाई की स्थिति की पुन: गणना करते हैं।

मुख्य लूप की पुनरावृत्ति के बाद, हमें कैमरे की स्थिति को अपडेट करना होगा, इसलिए update फ़ंक्शन मौजूद है। यह सिर्फ camera_func फ़ंक्शन को कॉल करके राज्य को camera_func है, जो हमारे लिए सभी कड़ी मेहनत करेंगे। हम इसे बाद में लागू करते हैं

चलो कैमरे के एक instace बनाएँ:

 for row in level: ... total_level_width = len(level[0])*32 # calculate size of level in pixels total_level_height = len(level)*32 # maybe make 32 an constant camera = Camera(*to_be_implemented*, total_level_width, total_level_height) entities.add(player) ... 

और हमारी मुख्य लूप में परिवर्तन:

 # draw background for y in range(32): ... camera.update(player) # camera follows player. Note that we could also follow any other sprite # update player, draw everything else player.update(up, down, left, right, running, platforms) for e in entities: # apply the offset to each entity. # call this for everything that should scroll, # which is basically everything other than GUI/HUD/UI screen.blit(e.image, camera.apply(e)) pygame.display.update() 

हमारा कैमरा वर्ग पहले से ही बहुत लचीला है और अभी तक मृत सरल है। यह अलग-अलग प्रकार के स्क्रॉलिंग का उपयोग कर सकता है (अलग-अलग camera_func फ़ंक्शन प्रदान करके), और यह केवल किसी खिलाड़ी के नहीं बल्कि किसी भी आकस्मिक प्रेत का अनुसरण कर सकता है। आप रनटाइम पर भी इसे बदल सकते हैं।

अब camera_func के कार्यान्वयन के लिए एक आसान तरीका यह है कि स्क्रीन पर केवल खिलाड़ी (या जो भी इंटैक्ट हम चाहते हैं) को केन्द्रित करना है, और कार्यान्वयन सीधे आगे है:

 def simple_camera(camera, target_rect): l, t, _, _ = target_rect # l = left, t = top _, _, w, h = camera # w = width, h = height return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h) 

हम सिर्फ हमारे target की स्थिति लेते हैं, और आधे कुल स्क्रीन आकार जोड़ते हैं। आप इसे अपने कैमरे बनाकर यह कोशिश कर सकते हैं:

 camera = Camera(simple_camera, total_level_width, total_level_height) 

अब तक सब ठीक है. लेकिन शायद हम स्तर के बाहर काली पृष्ठभूमि देखना नहीं चाहते हैं? कैसा रहेगा:

 def complex_camera(camera, target_rect): l, t, _, _ = target_rect _, _, w, h = camera l, t, _, _ = -l+HALF_WIDTH, -t+HALF_HEIGHT, w, h # center player l = min(0, l) # stop scrolling at the left edge l = max(-(camera.width-WIN_WIDTH), l) # stop scrolling at the right edge t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling at the bottom t = min(0, t) # stop scrolling at the top return Rect(l, t, w, h) 

यहां हम min / max कार्यों का उपयोग करने के लिए सुनिश्चित करें कि हम बाहर की तरफ स्क्रॉल न करें

इसे अपने कैमरे बनाकर इसे आज़माएं:

 camera = Camera(complex_camera, total_level_width, total_level_height) 

कार्रवाई में हमारी नई स्क्रॉलिंग का एक छोटा एनीमेशन है:

यहां छवि विवरण दर्ज करें

यहाँ पूरा कोड फिर से है (ध्यान दें मैंने आपके स्तर को थोड़ा बड़ा किया और कुछ और प्लेटफार्म बनाए हैं):

 #! /usr/bin/python import pygame from pygame import * WIN_WIDTH = 800 WIN_HEIGHT = 640 HALF_WIDTH = int(WIN_WIDTH / 2) HALF_HEIGHT = int(WIN_HEIGHT / 2) DISPLAY = (WIN_WIDTH, WIN_HEIGHT) DEPTH = 32 FLAGS = 0 CAMERA_SLACK = 30 def main(): global cameraX, cameraY pygame.init() screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH) pygame.display.set_caption("Use arrows to move!") timer = pygame.time.Clock() up = down = left = right = running = False bg = Surface((32,32)) bg.convert() bg.fill(Color("#000000")) entities = pygame.sprite.Group() player = Player(32, 32) platforms = [] x = y = 0 level = [ "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP", "PP", "PP", "PP", "P PPPPPPPPPPP P", "PP", "PP", "PP", "P PPPPPPPP P", "PP", "P PPPPPPP P", "P PPPPPP P", "PP", "P PPPPPPP P", "PP", "P PPPPPP P", "PP", "P PPPPPPPPPPP P", "PP", "P PPPPPPPPPPP P", "PP", "PP", "PP", "PP", "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",] # build the level for row in level: for col in row: if col == "P": p = Platform(x, y) platforms.append(p) entities.add(p) if col == "E": e = ExitBlock(x, y) platforms.append(e) entities.add(e) x += 32 y += 32 x = 0 total_level_width = len(level[0])*32 total_level_height = len(level)*32 camera = Camera(complex_camera, total_level_width, total_level_height) entities.add(player) while 1: timer.tick(60) for e in pygame.event.get(): if e.type == QUIT: raise SystemExit, "QUIT" if e.type == KEYDOWN and e.key == K_ESCAPE: raise SystemExit, "ESCAPE" if e.type == KEYDOWN and e.key == K_UP: up = True if e.type == KEYDOWN and e.key == K_DOWN: down = True if e.type == KEYDOWN and e.key == K_LEFT: left = True if e.type == KEYDOWN and e.key == K_RIGHT: right = True if e.type == KEYDOWN and e.key == K_SPACE: running = True if e.type == KEYUP and e.key == K_UP: up = False if e.type == KEYUP and e.key == K_DOWN: down = False if e.type == KEYUP and e.key == K_RIGHT: right = False if e.type == KEYUP and e.key == K_LEFT: left = False # draw background for y in range(32): for x in range(32): screen.blit(bg, (x * 32, y * 32)) camera.update(player) # update player, draw everything else player.update(up, down, left, right, running, platforms) for e in entities: screen.blit(e.image, camera.apply(e)) pygame.display.update() class Camera(object): def __init__(self, camera_func, width, height): self.camera_func = camera_func self.state = Rect(0, 0, width, height) def apply(self, target): return target.rect.move(self.state.topleft) def update(self, target): self.state = self.camera_func(self.state, target.rect) def simple_camera(camera, target_rect): l, t, _, _ = target_rect _, _, w, h = camera return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h) def complex_camera(camera, target_rect): l, t, _, _ = target_rect _, _, w, h = camera l, t, _, _ = -l+HALF_WIDTH, -t+HALF_HEIGHT, w, h l = min(0, l) # stop scrolling at the left edge l = max(-(camera.width-WIN_WIDTH), l) # stop scrolling at the right edge t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling at the bottom t = min(0, t) # stop scrolling at the top return Rect(l, t, w, h) class Entity(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) class Player(Entity): def __init__(self, x, y): Entity.__init__(self) self.xvel = 0 self.yvel = 0 self.onGround = False self.image = Surface((32,32)) self.image.fill(Color("#0000FF")) self.image.convert() self.rect = Rect(x, y, 32, 32) def update(self, up, down, left, right, running, platforms): if up: # only jump if on the ground if self.onGround: self.yvel -= 10 if down: pass if running: self.xvel = 12 if left: self.xvel = -8 if right: self.xvel = 8 if not self.onGround: # only accelerate with gravity if in the air self.yvel += 0.3 # max falling speed if self.yvel > 100: self.yvel = 100 if not(left or right): self.xvel = 0 # increment in x direction self.rect.left += self.xvel # do x-axis collisions self.collide(self.xvel, 0, platforms) # increment in y direction self.rect.top += self.yvel # assuming we're in the air self.onGround = False; # do y-axis collisions self.collide(0, self.yvel, platforms) def collide(self, xvel, yvel, platforms): for p in platforms: if pygame.sprite.collide_rect(self, p): if isinstance(p, ExitBlock): pygame.event.post(pygame.event.Event(QUIT)) if xvel > 0: self.rect.right = p.rect.left print "collide right" if xvel < 0: self.rect.left = p.rect.right print "collide left" if yvel > 0: self.rect.bottom = p.rect.top self.onGround = True self.yvel = 0 if yvel < 0: self.rect.top = p.rect.bottom class Platform(Entity): def __init__(self, x, y): Entity.__init__(self) self.image = Surface((32, 32)) self.image.convert() self.image.fill(Color("#DDDDDD")) self.rect = Rect(x, y, 32, 32) def update(self): pass class ExitBlock(Platform): def __init__(self, x, y): Platform.__init__(self, x, y) self.image.fill(Color("#0033FF")) if __name__ == "__main__": main() 

चूंकि सही पता है, आपके पास एक स्थैतिक पृष्ठभूमि है, और जिस खिलाड़ी को आप नियंत्रित करते हैं वह उस स्थिति में फहरा हुआ है, जिसमें वह है, आपके पास 2 विकल्प हमेशा मध्य में दिखाते हैं।

  1. यदि आप नक्शा छोटे enought है, तो आप एक बड़ा आईएमजी ए हो सकता है, और एक आयत प्राप्त कर सकते हैं, जो खिलाड़ी की स्थिति के आधार पर स्क्रीन के आकार का होगा। इस तरह, खिलाड़ी हमेशा बीच में होगा एक Rect.clamp (Rect) या Rect.clamp_ip (रीक्ट) उस में आपको सहायता करेगा

  2. एक और दृष्टिकोण स्क्रीन पर स्थिति के लिए एक अलग tuple है। प्लेयर के पास स्क्रीन के केंद्र में एक स्थिर मूल्य होगा, जबकि पृष्ठभूमि की स्थिति खिलाड़ी की स्थिति का नकारात्मक होगा।

ऐसा करने का एकमात्र तरीका है कि मानचित्र में तार्किक स्थिति को अलग करना, स्क्रीन पर भौतिक पदों से।

स्क्रीन पर अपने मानचित्र को वास्तव में चित्रित करने के लिए संबंधित कोई भी कोड – आपके मामले में आपके sprites के सभी .rect विशेषताओं – को ऐसा करना होगा कि स्क्रीन पर योर मैप का हिस्सा क्या वास्तव में उपयोग कर रहा है।

उदाहरण के लिए, आपकी स्क्रीन आपके नक्शे को शीर्ष स्थान पर स्थित स्थिति (10,10) के साथ प्रदर्शित कर रही हो सकती है – सभी प्रदर्शन से संबंधित कोड उन्हें (जो कि ऊपर दिए गए मामले हैं। .rect गुण हैं) वर्तमान लॉजिकल स्थिति से ऑफसेट स्क्रीन को घटाना चाहिए – (यह कहना है कि चरित्र मानचित्र कोनो (12,15) पर है – इसलिए, इसे (12,15) – (10, 10) -> (2, 5) * BLOCK_SIZE) पर बकाया जाना चाहिए BLOCK_SIZE ऊपर आपके उदाहरण में हार्डकोड किया गया है 32,32, ताकि आप इसे डिस्प्ले पर शारीरिक पिक्सेल स्थिति (2 * 32, 5 * 32) पर खींचना चाहते हैं।

(संकेत: इस तरह कड़ी मेहनत से बचें, अपने कोड की शुरुआत में इसे एक निरंतर घोषणा करें)