Python3+Pygame实现的射击游戏,很流畅,有音效
之前看到过很多人写的飞机大战,当然了之前我也写过多个版本,总体来说功能是实现了,但总感觉不够“炫”
今天浏览Python资料的时候,意外发现了这个很好的“射击”类游戏,看上去类似飞机大战,但更好玩
一、游戏特点
1. 运行非常流畅
2. 默认有3条命,每条命的HP可以增加(吃补品)也可以减少(被击中)
3. 有碰撞时的音效
4. 有碰撞时的爆炸效果
二、运行效果展示
三、完整代码
1 from __future__ import division
2 import pygame
3 import random
4 from os import path
5
6 ## assets folder
7 img_dir = path.join(path.dirname(__file__), 'assets')
8 sound_folder = path.join(path.dirname(__file__), 'sounds')
9
10 ###############################
11 ## to be placed in "constant.py" later
12 WIDTH = 480
13 HEIGHT = 600
14 FPS = 60
15 POWERUP_TIME = 5000
16 BAR_LENGTH = 100
17 BAR_HEIGHT = 10
18
19 # Define Colors
20 WHITE = (255, 255, 255)
21 BLACK = (0, 0, 0)
22 RED = (255, 0, 0)
23 GREEN = (0, 255, 0)
24 BLUE = (0, 0, 255)
25 YELLOW = (255, 255, 0)
26 ###############################
27
28 ###############################
29 ## to placed in "__init__.py" later
30 ## initialize pygame and create window
31 pygame.init()
32 pygame.mixer.init() ## For sound
33 screen = pygame.display.set_mode((WIDTH, HEIGHT))
34 pygame.display.set_caption("Space Shooter")
35 clock = pygame.time.Clock() ## For syncing the FPS
36 ###############################
37
38 font_name = pygame.font.match_font('arial')
39
40 def main_menu():
41 global screen
42
43 menu_song = pygame.mixer.music.load(path.join(sound_folder, "menu.ogg"))
44 pygame.mixer.music.play(-1)
45
46 title = pygame.image.load(path.join(img_dir, "main.png")).convert()
47 title = pygame.transform.scale(title, (WIDTH, HEIGHT), screen)
48
49 screen.blit(title, (0,0))
50 pygame.display.update()
51
52 while True:
53 ev = pygame.event.poll()
54 if ev.type == pygame.KEYDOWN:
55 if ev.key == pygame.K_RETURN:
56 break
57 elif ev.key == pygame.K_q:
58 pygame.quit()
59 quit()
60 else:
61 draw_text(screen, "Press [ENTER] To Begin", 30, WIDTH/2, HEIGHT/2)
62 draw_text(screen, "or [Q] To Quit", 30, WIDTH/2, (HEIGHT/2)+40)
63 pygame.display.update()
64
65 #pygame.mixer.music.stop()
66 ready = pygame.mixer.Sound(path.join(sound_folder,'getready.ogg'))
67 ready.play()
68 screen.fill(BLACK)
69 draw_text(screen, "GET READY!", 40, WIDTH/2, HEIGHT/2)
70 pygame.display.update()
71
72
73 def draw_text(surf, text, size, x, y):
74 ## selecting a cross platform font to display the score
75 font = pygame.font.Font(font_name, size)
76 text_surface = font.render(text, True, WHITE) ## True denotes the font to be anti-aliased
77 text_rect = text_surface.get_rect()
78 text_rect.midtop = (x, y)
79 surf.blit(text_surface, text_rect)
80
81
82 def draw_shield_bar(surf, x, y, pct):
83 # if pct < 0:
84 # pct = 0
85 pct = max(pct, 0)
86 ## moving them to top
87 # BAR_LENGTH = 100
88 # BAR_HEIGHT = 10
89 fill = (pct / 100) * BAR_LENGTH
90 outline_rect = pygame.Rect(x, y, BAR_LENGTH, BAR_HEIGHT)
91 fill_rect = pygame.Rect(x, y, fill, BAR_HEIGHT)
92 pygame.draw.rect(surf, GREEN, fill_rect)
93 pygame.draw.rect(surf, WHITE, outline_rect, 2)
94
95
96 def draw_lives(surf, x, y, lives, img):
97 for i in range(lives):
98 img_rect= img.get_rect()
99 img_rect.x = x + 30 * i
100 img_rect.y = y
101 surf.blit(img, img_rect)
102
103
104
105 def newmob():
106 mob_element = Mob()
107 all_sprites.add(mob_element)
108 mobs.add(mob_element)
109
110 class Explosion(pygame.sprite.Sprite):
111 def __init__(self, center, size):
112 pygame.sprite.Sprite.__init__(self)
113 self.size = size
114 self.image = explosion_anim[self.size][0]
115 self.rect = self.image.get_rect()
116 self.rect.center = center
117 self.frame = 0
118 self.last_update = pygame.time.get_ticks()
119 self.frame_rate = 75
120
121 def update(self):
122 now = pygame.time.get_ticks()
123 if now - self.last_update > self.frame_rate:
124 self.last_update = now
125 self.frame += 1
126 if self.frame == len(explosion_anim[self.size]):
127 self.kill()
128 else:
129 center = self.rect.center
130 self.image = explosion_anim[self.size][self.frame]
131 self.rect = self.image.get_rect()
132 self.rect.center = center
133
134
135 class Player(pygame.sprite.Sprite):
136 def __init__(self):
137 pygame.sprite.Sprite.__init__(self)
138 ## scale the player img down
139 self.image = pygame.transform.scale(player_img, (50, 38))
140 self.image.set_colorkey(BLACK)
141 self.rect = self.image.get_rect()
142 self.radius = 20
143 self.rect.centerx = WIDTH / 2
144 self.rect.bottom = HEIGHT - 10
145 self.speedx = 0
146 self.shield = 100
147 self.shoot_delay = 250
148 self.last_shot = pygame.time.get_ticks()
149 self.lives = 3
150 self.hidden = False
151 self.hide_timer = pygame.time.get_ticks()
152 self.power = 1
153 self.power_timer = pygame.time.get_ticks()
154
155 def update(self):
156 ## time out for powerups
157 if self.power >=2 and pygame.time.get_ticks() - self.power_time > POWERUP_TIME:
158 self.power -= 1
159 self.power_time = pygame.time.get_ticks()
160
161 ## unhide
162 if self.hidden and pygame.time.get_ticks() - self.hide_timer > 1000:
163 self.hidden = False
164 self.rect.centerx = WIDTH / 2
165 self.rect.bottom = HEIGHT - 30
166
167 self.speedx = 0 ## makes the player static in the screen by default.
168 # then we have to check whether there is an event hanlding being done for the arrow keys being
169 ## pressed
170
171 ## will give back a list of the keys which happen to be pressed down at that moment
172 keystate = pygame.key.get_pressed()
173 if keystate[pygame.K_LEFT]:
174 self.speedx = -5
175 elif keystate[pygame.K_RIGHT]:
176 self.speedx = 5
177
178 #Fire weapons by holding spacebar
179 if keystate[pygame.K_SPACE]:
180 self.shoot()
181
182 ## check for the borders at the left and right
183 if self.rect.right > WIDTH:
184 self.rect.right = WIDTH
185 if self.rect.left < 0:
186 self.rect.left = 0
187
188 self.rect.x += self.speedx
189
190 def shoot(self):
191 ## to tell the bullet where to spawn
192 now = pygame.time.get_ticks()
193 if now - self.last_shot > self.shoot_delay:
194 self.last_shot = now
195 if self.power == 1:
196 bullet = Bullet(self.rect.centerx, self.rect.top)
197 all_sprites.add(bullet)
198 bullets.add(bullet)
199 shooting_sound.play()
200 if self.power == 2:
201 bullet1 = Bullet(self.rect.left, self.rect.centery)
202 bullet2 = Bullet(self.rect.right, self.rect.centery)
203 all_sprites.add(bullet1)
204 all_sprites.add(bullet2)
205 bullets.add(bullet1)
206 bullets.add(bullet2)
207 shooting_sound.play()
208
209 """ MOAR POWAH """
210 if self.power >= 3:
211 bullet1 = Bullet(self.rect.left, self.rect.centery)
212 bullet2 = Bullet(self.rect.right, self.rect.centery)
213 missile1 = Missile(self.rect.centerx, self.rect.top) # Missile shoots from center of ship
214 all_sprites.add(bullet1)
215 all_sprites.add(bullet2)
216 all_sprites.add(missile1)
217 bullets.add(bullet1)
218 bullets.add(bullet2)
219 bullets.add(missile1)
220 shooting_sound.play()
221 missile_sound.play()
222
223 def powerup(self):
224 self.power += 1
225 self.power_time = pygame.time.get_ticks()
226
227 def hide(self):
228 self.hidden = True
229 self.hide_timer = pygame.time.get_ticks()
230 self.rect.center = (WIDTH / 2, HEIGHT + 200)
231
232
233 # defines the enemies
234 class Mob(pygame.sprite.Sprite):
235 def __init__(self):
236 pygame.sprite.Sprite.__init__(self)
237 self.image_orig = random.choice(meteor_images)
238 self.image_orig.set_colorkey(BLACK)
239 self.image = self.image_orig.copy()
240 self.rect = self.image.get_rect()
241 self.radius = int(self.rect.width *.90 / 2)
242 self.rect.x = random.randrange(0, WIDTH - self.rect.width)
243 self.rect.y = random.randrange(-150, -100)
244 self.speedy = random.randrange(5, 20) ## for randomizing the speed of the Mob
245
246 ## randomize the movements a little more
247 self.speedx = random.randrange(-3, 3)
248
249 ## adding rotation to the mob element
250 self.rotation = 0
251 self.rotation_speed = random.randrange(-8, 8)
252 self.last_update = pygame.time.get_ticks() ## time when the rotation has to happen
253
254 def rotate(self):
255 time_now = pygame.time.get_ticks()
256 if time_now - self.last_update > 50: # in milliseconds
257 self.last_update = time_now
258 self.rotation = (self.rotation + self.rotation_speed) % 360
259 new_image = pygame.transform.rotate(self.image_orig, self.rotation)
260 old_center = self.rect.center
261 self.image = new_image
262 self.rect = self.image.get_rect()
263 self.rect.center = old_center
264
265 def update(self):
266 self.rotate()
267 self.rect.x += self.speedx
268 self.rect.y += self.speedy
269 ## now what if the mob element goes out of the screen
270
271 if (self.rect.top > HEIGHT + 10) or (self.rect.left < -25) or (self.rect.right > WIDTH + 20):
272 self.rect.x = random.randrange(0, WIDTH - self.rect.width)
273 self.rect.y = random.randrange(-100, -40)
274 self.speedy = random.randrange(1, 8) ## for randomizing the speed of the Mob
275
276 ## defines the sprite for Powerups
277 class Pow(pygame.sprite.Sprite):
278 def __init__(self, center):
279 pygame.sprite.Sprite.__init__(self)
280 self.type = random.choice(['shield', 'gun'])
281 self.image = powerup_images[self.type]
282 self.image.set_colorkey(BLACK)
283 self.rect = self.image.get_rect()
284 ## place the bullet according to the current position of the player
285 self.rect.center = center
286 self.speedy = 2
287
288 def update(self):
289 """should spawn right in front of the player"""
290 self.rect.y += self.speedy
291 ## kill the sprite after it moves over the top border
292 if self.rect.top > HEIGHT:
293 self.kill()
294
295
296
297 ## defines the sprite for bullets
298 class Bullet(pygame.sprite.Sprite):
299 def __init__(self, x, y):
300 pygame.sprite.Sprite.__init__(self)
301 self.image = bullet_img
302 self.image.set_colorkey(BLACK)
303 self.rect = self.image.get_rect()
304 ## place the bullet according to the current position of the player
305 self.rect.bottom = y
306 self.rect.centerx = x
307 self.speedy = -10
308
309 def update(self):
310 """should spawn right in front of the player"""
311 self.rect.y += self.speedy
312 ## kill the sprite after it moves over the top border
313 if self.rect.bottom < 0:
314 self.kill()
315
316 ## now we need a way to shoot
317 ## lets bind it to "spacebar".
318 ## adding an event for it in Game loop
319
320 ## FIRE ZE MISSILES
321 class Missile(pygame.sprite.Sprite):
322 def __init__(self, x, y):
323 pygame.sprite.Sprite.__init__(self)
324 self.image = missile_img
325 self.image.set_colorkey(BLACK)
326 self.rect = self.image.get_rect()
327 self.rect.bottom = y
328 self.rect.centerx = x
329 self.speedy = -10
330
331 def update(self):
332 """should spawn right in front of the player"""
333 self.rect.y += self.speedy
334 if self.rect.bottom < 0:
335 self.kill()
336
337
338 ###################################################
339 ## Load all game images
340
341 background = pygame.image.load(path.join(img_dir, 'starfield.png')).convert()
342 background_rect = background.get_rect()
343 ## ^^ draw this rect first
344
345 player_img = pygame.image.load(path.join(img_dir, 'playerShip1_orange.png')).convert()
346 player_mini_img = pygame.transform.scale(player_img, (25, 19))
347 player_mini_img.set_colorkey(BLACK)
348 bullet_img = pygame.image.load(path.join(img_dir, 'laserRed16.png')).convert()
349 missile_img = pygame.image.load(path.join(img_dir, 'missile.png')).convert_alpha()
350 # meteor_img = pygame.image.load(path.join(img_dir, 'meteorBrown_med1.png')).convert()
351 meteor_images = []
352 meteor_list = [
353 'meteorBrown_big1.png',
354 'meteorBrown_big2.png',
355 'meteorBrown_med1.png',
356 'meteorBrown_med3.png',
357 'meteorBrown_small1.png',
358 'meteorBrown_small2.png',
359 'meteorBrown_tiny1.png'
360 ]
361
362 for image in meteor_list:
363 meteor_images.append(pygame.image.load(path.join(img_dir, image)).convert())
364
365 ## meteor explosion
366 explosion_anim = {}
367 explosion_anim['lg'] = []
368 explosion_anim['sm'] = []
369 explosion_anim['player'] = []
370 for i in range(9):
371 filename = 'regularExplosion0{}.png'.format(i)
372 img = pygame.image.load(path.join(img_dir, filename)).convert()
373 img.set_colorkey(BLACK)
374 ## resize the explosion
375 img_lg = pygame.transform.scale(img, (75, 75))
376 explosion_anim['lg'].append(img_lg)
377 img_sm = pygame.transform.scale(img, (32, 32))
378 explosion_anim['sm'].append(img_sm)
379
380 ## player explosion
381 filename = 'sonicExplosion0{}.png'.format(i)
382 img = pygame.image.load(path.join(img_dir, filename)).convert()
383 img.set_colorkey(BLACK)
384 explosion_anim['player'].append(img)
385
386 ## load power ups
387 powerup_images = {}
388 powerup_images['shield'] = pygame.image.load(path.join(img_dir, 'shield_gold.png')).convert()
389 powerup_images['gun'] = pygame.image.load(path.join(img_dir, 'bolt_gold.png')).convert()
390
391
392 ###################################################
393
394
395 ###################################################
396 ### Load all game sounds
397 shooting_sound = pygame.mixer.Sound(path.join(sound_folder, 'pew.wav'))
398 missile_sound = pygame.mixer.Sound(path.join(sound_folder, 'rocket.ogg'))
399 expl_sounds = []
400 for sound in ['expl3.wav', 'expl6.wav']:
401 expl_sounds.append(pygame.mixer.Sound(path.join(sound_folder, sound)))
402 ## main background music
403 #pygame.mixer.music.load(path.join(sound_folder, 'tgfcoder-FrozenJam-SeamlessLoop.ogg'))
404 pygame.mixer.music.set_volume(0.2) ## simmered the sound down a little
405
406 player_die_sound = pygame.mixer.Sound(path.join(sound_folder, 'rumble1.ogg'))
407 ###################################################
408
409 ## group all the sprites together for ease of update
410 all_sprites = pygame.sprite.Group()
411 player = Player()
412 all_sprites.add(player)
413
414 ## spawn a group of mob
415 mobs = pygame.sprite.Group()
416 for i in range(8): ## 8 mobs
417 # mob_element = Mob()
418 # all_sprites.add(mob_element)
419 # mobs.add(mob_element)
420 newmob()
421
422 ## group for bullets
423 bullets = pygame.sprite.Group()
424 powerups = pygame.sprite.Group()
425
426 #### Score board variable
427 score = 0
428
429 ## TODO: make the game music loop over again and again. play(loops=-1) is not working
430 # Error :
431 # TypeError: play() takes no keyword arguments
432 #pygame.mixer.music.play()
433
434 #############################
435 ## Game loop
436 running = True
437 menu_display = True
438 while running:
439 if menu_display:
440 main_menu()
441 pygame.time.wait(3000)
442
443 #Stop menu music
444 pygame.mixer.music.stop()
445 #Play the gameplay music
446 pygame.mixer.music.load(path.join(sound_folder, 'tgfcoder-FrozenJam-SeamlessLoop.ogg'))
447 pygame.mixer.music.play(-1) ## makes the gameplay sound in an endless loop
448
449 menu_display = False
450
451 #1 Process input/events
452 clock.tick(FPS) ## will make the loop run at the same speed all the time
453 for event in pygame.event.get(): # gets all the events which have occured till now and keeps tab of them.
454 ## listening for the the X button at the top
455 if event.type == pygame.QUIT:
456 running = False
457
458 ## Press ESC to exit game
459 if event.type == pygame.KEYDOWN:
460 if event.key == pygame.K_ESCAPE:
461 running = False
462 # ## event for shooting the bullets
463 # elif event.type == pygame.KEYDOWN:
464 # if event.key == pygame.K_SPACE:
465 # player.shoot() ## we have to define the shoot() function
466
467 #2 Update
468 all_sprites.update()
469
470
471 ## check if a bullet hit a mob
472 ## now we have a group of bullets and a group of mob
473 hits = pygame.sprite.groupcollide(mobs, bullets, True, True)
474 ## now as we delete the mob element when we hit one with a bullet, we need to respawn them again
475 ## as there will be no mob_elements left out
476 for hit in hits:
477 score += 50 - hit.radius ## give different scores for hitting big and small metoers
478 random.choice(expl_sounds).play()
479 # m = Mob()
480 # all_sprites.add(m)
481 # mobs.add(m)
482 expl = Explosion(hit.rect.center, 'lg')
483 all_sprites.add(expl)
484 if random.random() > 0.9:
485 pow = Pow(hit.rect.center)
486 all_sprites.add(pow)
487 powerups.add(pow)
488 newmob() ## spawn a new mob
489
490 ## ^^ the above loop will create the amount of mob objects which were killed spawn again
491 #########################
492
493 ## check if the player collides with the mob
494 hits = pygame.sprite.spritecollide(player, mobs, True, pygame.sprite.collide_circle) ## gives back a list, True makes the mob element disappear
495 for hit in hits:
496 player.shield -= hit.radius * 2
497 expl = Explosion(hit.rect.center, 'sm')
498 all_sprites.add(expl)
499 newmob()
500 if player.shield <= 0:
501 player_die_sound.play()
502 death_explosion = Explosion(player.rect.center, 'player')
503 all_sprites.add(death_explosion)
504 # running = False ## GAME OVER 3:D
505 player.hide()
506 player.lives -= 1
507 player.shield = 100
508
509 ## if the player hit a power up
510 hits = pygame.sprite.spritecollide(player, powerups, True)
511 for hit in hits:
512 if hit.type == 'shield':
513 player.shield += random.randrange(10, 30)
514 if player.shield >= 100:
515 player.shield = 100
516 if hit.type == 'gun':
517 player.powerup()
518
519 ## if player died and the explosion has finished, end game
520 if player.lives == 0 and not death_explosion.alive():
521 running = False
522 # menu_display = True
523 # pygame.display.update()
524
525 #3 Draw/render
526 screen.fill(BLACK)
527 ## draw the stargaze.png image
528 screen.blit(background, background_rect)
529
530 all_sprites.draw(screen)
531 draw_text(screen, str(score), 18, WIDTH / 2, 10) ## 10px down from the screen
532 draw_shield_bar(screen, 5, 5, player.shield)
533
534 # Draw lives
535 draw_lives(screen, WIDTH - 100, 5, player.lives, player_mini_img)
536
537 ## Done after drawing everything to the screen
538 pygame.display.flip()
539
540 pygame.quit()
四、运行方式
如果想要运行本程序,流程如下
1. 下载上述代码 例如存储为xxxx.py
2. 下载素材(图片、声音等)https://www.itprojects.cn/197.html
3. 切换到安装有pygame模块的python虚拟环境(如果没有pygame可以pip install pygame安装)
4. 使用命令运行 python3 xxxx.py
别忘了点赞哦,谢谢大家支持。如果想要做更多的pygame相关的程序,请发私信或者留言 1小时必回复
Python3+Pygame实现的射击游戏,很流畅,有音效的更多相关文章
- 练手项目:利用pygame库编写射击游戏
本项目使用pygame模块编写了射击游戏,目的在于训练自己的Python基本功.了解中小型程序框架以及学习代码重构等.游戏具有一定的可玩性,感兴趣的可以试一下. 项目说明:出自<Python编程 ...
- Python3+pygame实现的flappy bird游戏,代码完整,还有音乐
之前一直在手机上玩flappy bird游戏,闲暇时间就编写了一个 是采用python3+pygame模块制作而成的,运行效果非常流畅,会让你大吃一惊哦哈哈 一.运行效果展示 下载游戏之后,注意在自己 ...
- Golang+Protobuf+PixieJS 开发 Web 多人在线射击游戏(原创翻译)
简介 Superstellar 是一款开源的多人 Web 太空游戏,非常适合入门 Golang 游戏服务器开发. 规则很简单:摧毁移动的物体,不要被其他玩家和小行星杀死.你拥有两种资源 - 生命值(h ...
- 一款简单射击游戏IOS源码
源码描述: 一款基于cocos2d的简单设计游戏,并且也是一款基于cocos2d的简单射击游戏(含苹果IAD广告), 游戏操作很简单,哪个数字大就点击射击哪个.里面有苹果iad广告,功能简单完整,适合 ...
- D3D游戏编程系列(六):自己动手编写第一人称射击游戏之第一人称视角的构建
说起第一人称射击游戏,不得不提第一人称视角啊,没有这个,那么这个第一就无从谈起啊,我作为一个观察者究竟如何在这个地图上顺利的移动和观察呢,那么,我们一起来研究下. 我们首先来看下CDXCamera类: ...
- pygame开发滑雪者游戏
pygame开发滑雪者游戏 一.实验说明 下述介绍为实验楼默认环境,如果您使用的是定制环境,请修改成您自己的环境介绍. 1. 环境登录 无需密码自动登录,系统用户名 shiyanlou,该用户具备 s ...
- python学习笔记(七) 类和pygame实现打飞机游戏
python中类声明如下: class Student(object): def __init__(self, name, score): self.name = name self.score = ...
- 使用Cocos2dx-JS开发一个飞行射击游戏
一.前言 笔者闲来无事,某天github闲逛,看到了游戏引擎的专题,引起了自己的兴趣,于是就自己捣腾了一下Cocos2dx-JS.由于是学习,所谓纸上得来终觉浅,只是看文档看sample看demo,并 ...
- Python3+pygame实现的90坦克大战 代码完整 有演示效果
我是一个典型的80后,年轻时玩过了特别多的游戏,所以这几天用Python3+pygame实现了一个另外小游戏"坦克大战"(其他的游戏,请翻阅我的博客) 本实例代码量有些多,完整的版 ...
随机推荐
- Kafka 博文索引
博文索引 KafkaBroker 简析 KafkaConsumer 简析 KafkaProducer 简析 KafkaMirrorMaker 的不足以及一些改进 Kafka 简介 数据是系统的燃料,系 ...
- Linux Bash Script loop
Linux Bash Script loop shell 编程之流程控制 for 循环.while 循环和 until 循环 for var in item1 item2 ... itemN do c ...
- when I was installing github for windows ,some errors occurred !
1: 2: 3: 4: install.log error messages:
- Semantic Pull Requests All In One
Semantic Pull Requests All In One https://github.com/zeke/semantic-pull-requests docs: Update direct ...
- 正则表达式 test 踩坑指南
正则表达式 test 踩坑指南 test 只能使用一次,第二次返回的是错误结果! reg = /edg|edge/g; /edg|edge/g reg.test(`edg`) true reg.tes ...
- Get your site working on Google Search Console , 在 Google Search Console中运行您的网站, Google Search Console
1 1 https://support.google.com/webmasters/topic/4564315? Search Console Help SEARCH CONSOLEHELP FORU ...
- web 安全 & web 攻防: XSS(跨站脚本攻击)和 CSRF(跨站请求伪造)
web 安全 & web 攻防: XSS(跨站脚本攻击)和 CSRF(跨站请求伪造) XSS(跨站脚本攻击)和CSRF(跨站请求伪造) Cross-site Scripting (XSS) h ...
- macOS & pbcopy
macOS & pbcopy copy from command line pbcopy $ whoami | pbcopy # xgqfrms-mbp $ echo "hello, ...
- JavaScript Number Type Checker
JavaScript Number Type Checker Number.isInteger // static 方法 Number.isInteger(value) https://develop ...
- Chrome & targetText
Chrome & targetText target text http://www.ruanyifeng.com/blog/2019/03/weekly-issue-47.html http ...